Line data Source code
1 : /*
2 : * Unix SMB/CIFS implementation.
3 : *
4 : * WINREG internal client routines
5 : *
6 : * Copyright (c) 2011 Andreas Schneider <asn@samba.org>
7 : *
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.
12 : *
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.
17 : *
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/>.
20 : */
21 :
22 : #include "includes.h"
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"
27 : #include "../lib/tsocket/tsocket.h"
28 :
29 : /**
30 : * Split path into hive name and subkeyname
31 : * normalizations performed:
32 : * - if the path contains no '\\' characters,
33 : * assume that the legacy format of using '/'
34 : * as a separator is used and convert '/' to '\\'
35 : * - strip trailing '\\' chars
36 : */
37 0 : static WERROR _split_hive_key(TALLOC_CTX *mem_ctx,
38 : const char *path,
39 : char **hivename,
40 : char **subkeyname)
41 : {
42 0 : char *p;
43 0 : const char *tmp_subkeyname;
44 :
45 0 : if ((path == NULL) || (hivename == NULL) || (subkeyname == NULL)) {
46 0 : return WERR_INVALID_PARAMETER;
47 : }
48 :
49 0 : if (strlen(path) == 0) {
50 0 : return WERR_INVALID_PARAMETER;
51 : }
52 :
53 0 : if (strchr(path, '\\') == NULL) {
54 0 : *hivename = talloc_string_sub(mem_ctx, path, "/", "\\");
55 : } else {
56 0 : *hivename = talloc_strdup(mem_ctx, path);
57 : }
58 :
59 0 : if (*hivename == NULL) {
60 0 : return WERR_NOT_ENOUGH_MEMORY;
61 : }
62 :
63 : /* strip trailing '\\' chars */
64 0 : p = strrchr(*hivename, '\\');
65 0 : while ((p != NULL) && (p[1] == '\0')) {
66 0 : *p = '\0';
67 0 : p = strrchr(*hivename, '\\');
68 : }
69 :
70 0 : p = strchr(*hivename, '\\');
71 :
72 0 : if ((p == NULL) || (*p == '\0')) {
73 : /* just the hive - no subkey given */
74 0 : tmp_subkeyname = "";
75 : } else {
76 0 : *p = '\0';
77 0 : tmp_subkeyname = p+1;
78 : }
79 0 : *subkeyname = talloc_strdup(mem_ctx, tmp_subkeyname);
80 0 : if (*subkeyname == NULL) {
81 0 : return WERR_NOT_ENOUGH_MEMORY;
82 : }
83 :
84 0 : return WERR_OK;
85 : }
86 :
87 420 : static NTSTATUS _winreg_int_openkey(TALLOC_CTX *mem_ctx,
88 : const struct auth_session_info *session_info,
89 : struct messaging_context *msg_ctx,
90 : struct dcerpc_binding_handle **h,
91 : uint32_t reg_type,
92 : const char *key,
93 : bool create_key,
94 : uint32_t access_mask,
95 : struct policy_handle *hive_handle,
96 : struct policy_handle *key_handle,
97 : WERROR *pwerr)
98 : {
99 0 : struct tsocket_address *local;
100 0 : struct dcerpc_binding_handle *binding_handle;
101 0 : struct winreg_String wkey, wkeyclass;
102 0 : NTSTATUS status;
103 420 : WERROR result = WERR_OK;
104 0 : int rc;
105 :
106 420 : rc = tsocket_address_inet_from_strings(mem_ctx,
107 : "ip",
108 : "127.0.0.1",
109 : 0,
110 : &local);
111 420 : if (rc < 0) {
112 0 : return NT_STATUS_NO_MEMORY;
113 : }
114 :
115 420 : status = rpcint_binding_handle(mem_ctx,
116 : &ndr_table_winreg,
117 : local,
118 : NULL,
119 : session_info,
120 : msg_ctx,
121 : &binding_handle);
122 420 : if (!NT_STATUS_IS_OK(status)) {
123 0 : DBG_WARNING("Could not connect to winreg pipe: %s\n",
124 : nt_errstr(status));
125 0 : return status;
126 : }
127 :
128 420 : switch (reg_type) {
129 420 : case HKEY_LOCAL_MACHINE:
130 420 : status = dcerpc_winreg_OpenHKLM(binding_handle,
131 : mem_ctx,
132 : NULL,
133 : access_mask,
134 : hive_handle,
135 : &result);
136 420 : break;
137 0 : case HKEY_CLASSES_ROOT:
138 0 : status = dcerpc_winreg_OpenHKCR(binding_handle,
139 : mem_ctx,
140 : NULL,
141 : access_mask,
142 : hive_handle,
143 : &result);
144 0 : break;
145 0 : case HKEY_USERS:
146 0 : status = dcerpc_winreg_OpenHKU(binding_handle,
147 : mem_ctx,
148 : NULL,
149 : access_mask,
150 : hive_handle,
151 : &result);
152 0 : break;
153 0 : case HKEY_CURRENT_USER:
154 0 : status = dcerpc_winreg_OpenHKCU(binding_handle,
155 : mem_ctx,
156 : NULL,
157 : access_mask,
158 : hive_handle,
159 : &result);
160 0 : break;
161 0 : case HKEY_PERFORMANCE_DATA:
162 0 : status = dcerpc_winreg_OpenHKPD(binding_handle,
163 : mem_ctx,
164 : NULL,
165 : access_mask,
166 : hive_handle,
167 : &result);
168 0 : break;
169 0 : default:
170 0 : result = WERR_INVALID_PARAMETER;
171 0 : status = NT_STATUS_OK;
172 : }
173 420 : if (!NT_STATUS_IS_OK(status)) {
174 0 : talloc_free(binding_handle);
175 0 : return status;
176 : }
177 420 : if (!W_ERROR_IS_OK(result)) {
178 0 : talloc_free(binding_handle);
179 0 : *pwerr = result;
180 0 : return status;
181 : }
182 :
183 420 : ZERO_STRUCT(wkey);
184 420 : wkey.name = key;
185 :
186 420 : if (create_key) {
187 0 : enum winreg_CreateAction action = REG_ACTION_NONE;
188 :
189 0 : ZERO_STRUCT(wkeyclass);
190 0 : wkeyclass.name = "";
191 :
192 0 : status = dcerpc_winreg_CreateKey(binding_handle,
193 : mem_ctx,
194 : hive_handle,
195 : wkey,
196 : wkeyclass,
197 : 0,
198 : access_mask,
199 : NULL,
200 : key_handle,
201 : &action,
202 : &result);
203 0 : switch (action) {
204 0 : case REG_ACTION_NONE:
205 0 : DEBUG(8, ("dcerpc_winreg_int_openkey: createkey"
206 : " did nothing -- huh?\n"));
207 0 : break;
208 0 : case REG_CREATED_NEW_KEY:
209 0 : DEBUG(8, ("dcerpc_winreg_int_openkey: createkey"
210 : " created %s\n", key));
211 0 : break;
212 0 : case REG_OPENED_EXISTING_KEY:
213 0 : DEBUG(8, ("dcerpc_winreg_int_openkey: createkey"
214 : " opened existing %s\n", key));
215 0 : break;
216 : }
217 : } else {
218 420 : status = dcerpc_winreg_OpenKey(binding_handle,
219 : mem_ctx,
220 : hive_handle,
221 : wkey,
222 : 0,
223 : access_mask,
224 : key_handle,
225 : &result);
226 : }
227 420 : if (!NT_STATUS_IS_OK(status)) {
228 0 : talloc_free(binding_handle);
229 0 : return status;
230 : }
231 420 : if (!W_ERROR_IS_OK(result)) {
232 0 : talloc_free(binding_handle);
233 0 : *pwerr = result;
234 0 : return status;
235 : }
236 :
237 420 : *h = binding_handle;
238 :
239 420 : return status;
240 : }
241 :
242 0 : NTSTATUS dcerpc_winreg_int_openkey(TALLOC_CTX *mem_ctx,
243 : const struct auth_session_info *server_info,
244 : struct messaging_context *msg_ctx,
245 : struct dcerpc_binding_handle **h,
246 : const char *key,
247 : bool create_key,
248 : uint32_t access_mask,
249 : struct policy_handle *hive_handle,
250 : struct policy_handle *key_handle,
251 : WERROR *pwerr)
252 : {
253 0 : char *hivename = NULL;
254 0 : char *subkey = NULL;
255 0 : uint32_t reg_type;
256 0 : WERROR result;
257 :
258 0 : result = _split_hive_key(mem_ctx, key, &hivename, &subkey);
259 0 : if (!W_ERROR_IS_OK(result)) {
260 0 : *pwerr = result;
261 0 : return NT_STATUS_OK;
262 : }
263 :
264 0 : if (strequal(hivename, "HKLM") ||
265 0 : strequal(hivename, "HKEY_LOCAL_MACHINE")) {
266 0 : reg_type = HKEY_LOCAL_MACHINE;
267 0 : } else if (strequal(hivename, "HKCR") ||
268 0 : strequal(hivename, "HKEY_CLASSES_ROOT")) {
269 0 : reg_type = HKEY_CLASSES_ROOT;
270 0 : } else if (strequal(hivename, "HKU") ||
271 0 : strequal(hivename, "HKEY_USERS")) {
272 0 : reg_type = HKEY_USERS;
273 0 : } else if (strequal(hivename, "HKCU") ||
274 0 : strequal(hivename, "HKEY_CURRENT_USER")) {
275 0 : reg_type = HKEY_CURRENT_USER;
276 0 : } else if (strequal(hivename, "HKPD") ||
277 0 : strequal(hivename, "HKEY_PERFORMANCE_DATA")) {
278 0 : reg_type = HKEY_PERFORMANCE_DATA;
279 : } else {
280 0 : DEBUG(10,("dcerpc_winreg_int_openkey: unrecognised hive key %s\n",
281 : key));
282 0 : *pwerr = WERR_INVALID_PARAMETER;
283 0 : return NT_STATUS_OK;
284 : }
285 :
286 0 : return _winreg_int_openkey(mem_ctx,
287 : server_info,
288 : msg_ctx,
289 : h,
290 : reg_type,
291 : key,
292 : create_key,
293 : access_mask,
294 : hive_handle,
295 : key_handle,
296 : pwerr);
297 : }
298 :
299 420 : NTSTATUS dcerpc_winreg_int_hklm_openkey(TALLOC_CTX *mem_ctx,
300 : const struct auth_session_info *server_info,
301 : struct messaging_context *msg_ctx,
302 : struct dcerpc_binding_handle **h,
303 : const char *key,
304 : bool create_key,
305 : uint32_t access_mask,
306 : struct policy_handle *hive_handle,
307 : struct policy_handle *key_handle,
308 : WERROR *pwerr)
309 : {
310 420 : return _winreg_int_openkey(mem_ctx,
311 : server_info,
312 : msg_ctx,
313 : h,
314 : HKEY_LOCAL_MACHINE,
315 : key,
316 : create_key,
317 : access_mask,
318 : hive_handle,
319 : key_handle,
320 : pwerr);
321 : }
322 :
323 : /* vim: set ts=8 sw=8 noet cindent syntax=c.doxygen: */
|