2 Samba Unix/Linux SMB implementation
3 RPC backend for the registry library
4 Copyright (C) 2003-2004 Jelmer Vernooij, jelmer@samba.org
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
22 #include "librpc/gen_ndr/ndr_winreg_c.h"
24 static struct hive_operations reg_backend_rpc
;
27 * This is the RPC backend for the registry library.
30 static void init_winreg_String(struct winreg_String
*name
, const char *s
)
36 #define openhive(u) static WERROR open_ ## u(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *hnd) \
38 struct winreg_Open ## u r; \
41 r.in.system_name = NULL; \
42 r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; \
45 status = dcerpc_winreg_Open ## u(p, mem_ctx, &r); \
46 if (NT_STATUS_IS_ERR(status)) {\
47 DEBUG(0,("Error executing open\n"));\
48 return ntstatus_to_werror(status);\
63 struct policy_handle pol
;
72 WERROR (*open
) (struct dcerpc_pipe
*p
, TALLOC_CTX
*, struct policy_handle
*h
);
74 { HKEY_LOCAL_MACHINE
, open_HKLM
},
75 { HKEY_CURRENT_USER
, open_HKCU
},
76 { HKEY_CLASSES_ROOT
, open_HKCR
},
77 { HKEY_PERFORMANCE_DATA
, open_HKPD
},
78 { HKEY_USERS
, open_HKU
},
79 { HKEY_DYN_DATA
, open_HKDD
},
80 { HKEY_CURRENT_CONFIG
, open_HKCC
},
84 static WERROR
rpc_query_key(const struct registry_key
*k
);
86 static WERROR
rpc_get_predefined_key (struct registry_context
*ctx
, uint32_t hkey_type
, struct registry_key
**k
)
89 struct registry_hive
*h
;
90 struct rpc_key_data
*mykeydata
;
92 for(n
= 0; known_hives
[n
].hkey
; n
++)
94 if(known_hives
[n
].hkey
== hkey_type
) break;
97 if(!known_hives
[n
].open
) {
98 DEBUG(1, ("No such hive %d\n", hkey_type
));
99 return WERR_NO_MORE_ITEMS
;
102 h
= talloc(ctx
, struct registry_hive
);
103 h
->functions
= ®_backend_rpc
;
105 h
->backend_data
= ctx
->backend_data
;
107 (*k
) = h
->root
= talloc(h
, struct registry_key
);
109 (*k
)->backend_data
= mykeydata
= talloc(*k
, struct rpc_key_data
);
110 mykeydata
->num_values
= -1;
111 mykeydata
->num_subkeys
= -1;
112 return known_hives
[n
].open((struct dcerpc_pipe
*)ctx
->backend_data
, *k
, &(mykeydata
->pol
));
116 static WERROR
rpc_key_put_rpc_data(TALLOC_CTX
*mem_ctx
, struct registry_key
*k
)
118 struct winreg_OpenKey r
;
119 struct rpc_key_data
*mykeydata
;
121 k
->backend_data
= mykeydata
= talloc(mem_ctx
, struct rpc_key_data
);
122 mykeydata
->num_values
= -1;
123 mykeydata
->num_subkeys
= -1;
125 /* Then, open the handle using the hive */
127 memset(&r
, 0, sizeof(struct winreg_OpenKey
));
128 r
.in
.handle
= &(((struct rpc_key_data
*)k
->hive
->root
->backend_data
)->pol
);
129 init_winreg_String(&r
.in
.keyname
, k
->path
);
130 r
.in
.unknown
= 0x00000000;
131 r
.in
.access_mask
= 0x02000000;
132 r
.out
.handle
= &mykeydata
->pol
;
134 dcerpc_winreg_OpenKey((struct dcerpc_pipe
*)k
->hive
->backend_data
, mem_ctx
, &r
);
140 static WERROR
rpc_open_key(TALLOC_CTX
*mem_ctx
, const struct registry_key
*h
, const char *name
, struct registry_key
**key
)
142 struct rpc_key_data
*mykeydata
;
143 struct winreg_OpenKey r
;
145 *key
= talloc(mem_ctx
, struct registry_key
);
146 (*key
)->name
= talloc_strdup(mem_ctx
, name
);
148 (*key
)->backend_data
= mykeydata
= talloc(mem_ctx
, struct rpc_key_data
);
149 mykeydata
->num_values
= -1;
150 mykeydata
->num_subkeys
= -1;
152 /* Then, open the handle using the hive */
154 memset(&r
, 0, sizeof(struct winreg_OpenKey
));
155 r
.in
.handle
= &(((struct rpc_key_data
*)h
->backend_data
)->pol
);
156 init_winreg_String(&r
.in
.keyname
, name
);
157 r
.in
.unknown
= 0x00000000;
158 r
.in
.access_mask
= 0x02000000;
159 r
.out
.handle
= &mykeydata
->pol
;
161 dcerpc_winreg_OpenKey((struct dcerpc_pipe
*)(h
->hive
->backend_data
), mem_ctx
, &r
);
166 static WERROR
rpc_get_value_by_index(TALLOC_CTX
*mem_ctx
, const struct registry_key
*parent
, int n
, struct registry_value
**value
)
168 struct rpc_key_data
*mykeydata
= parent
->backend_data
;
170 struct winreg_EnumValue r
;
171 uint32_t type
, len1
, zero
= 0;
173 struct winreg_StringBuf name
;
176 if(mykeydata
->num_values
== -1) {
177 error
= rpc_query_key(parent
);
178 if(!W_ERROR_IS_OK(error
)) return error
;
181 len1
= mykeydata
->max_valdatalen
;
184 name
.size
= mykeydata
->max_valnamelen
* 2;
187 r
.in
.handle
= &mykeydata
->pol
;
196 status
= dcerpc_winreg_EnumValue((struct dcerpc_pipe
*)parent
->hive
->backend_data
, mem_ctx
, &r
);
197 if(NT_STATUS_IS_ERR(status
)) {
198 DEBUG(0, ("Error in EnumValue: %s\n", nt_errstr(status
)));
199 return WERR_GENERAL_FAILURE
;
202 if(NT_STATUS_IS_OK(status
) &&
203 W_ERROR_IS_OK(r
.out
.result
) && r
.out
.length
) {
204 *value
= talloc(mem_ctx
, struct registry_value
);
205 (*value
)->name
= talloc_strdup(mem_ctx
, r
.out
.name
->name
);
206 (*value
)->data_type
= type
;
207 (*value
)->data
= data_blob_talloc(mem_ctx
, r
.out
.value
, *r
.out
.length
);
214 static WERROR
rpc_get_subkey_by_index(TALLOC_CTX
*mem_ctx
, const struct registry_key
*parent
, int n
, struct registry_key
**subkey
)
216 struct winreg_EnumKey r
;
217 struct rpc_key_data
*mykeydata
= parent
->backend_data
;
219 struct winreg_StringBuf namebuf
, classbuf
;
220 NTTIME change_time
= 0;
227 classbuf
.name
= NULL
;
229 r
.in
.handle
= &mykeydata
->pol
;
231 r
.in
.name
= &namebuf
;
232 r
.in
.class = &classbuf
;
233 r
.in
.last_changed_time
= &change_time
;
234 r
.out
.name
= &namebuf
;
236 status
= dcerpc_winreg_EnumKey((struct dcerpc_pipe
*)parent
->hive
->backend_data
, mem_ctx
, &r
);
237 if(NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(r
.out
.result
)) {
238 char *name
= talloc_strdup(mem_ctx
, r
.out
.name
->name
);
239 return rpc_open_key(mem_ctx
, parent
, name
, subkey
);
245 static WERROR
rpc_add_key(TALLOC_CTX
*mem_ctx
, const struct registry_key
*parent
, const char *name
, uint32_t access_mask
, struct security_descriptor
*sec
, struct registry_key
**key
)
248 struct winreg_CreateKey r
;
250 init_winreg_String(&r
.in
.name
, name
);
251 init_winreg_String(&r
.in
.class, NULL
);
253 r
.in
.handle
= parent
->backend_data
;
254 r
.out
.new_handle
= talloc(mem_ctx
, struct policy_handle
);
256 r
.in
.access_mask
= access_mask
;
259 status
= dcerpc_winreg_CreateKey((struct dcerpc_pipe
*)(parent
->hive
->backend_data
), mem_ctx
, &r
);
261 if (!NT_STATUS_IS_OK(status
)) {
262 DEBUG(1, ("CreateKey failed - %s\n", nt_errstr(status
)));
263 return ntstatus_to_werror(status
);
266 if (W_ERROR_IS_OK(r
.out
.result
)) {
267 *key
= talloc(mem_ctx
, struct registry_key
);
268 (*key
)->name
= talloc_strdup(*key
, name
);
269 (*key
)->backend_data
= r
.out
.new_handle
;
275 static WERROR
rpc_query_key(const struct registry_key
*k
)
278 struct winreg_QueryInfoKey r
;
279 struct rpc_key_data
*mykeydata
= k
->backend_data
;
280 TALLOC_CTX
*mem_ctx
= talloc_init("query_key");
282 init_winreg_String(&r
.in
.class, NULL
);
283 r
.in
.handle
= &mykeydata
->pol
;
285 status
= dcerpc_winreg_QueryInfoKey((struct dcerpc_pipe
*)(k
->hive
->backend_data
), mem_ctx
, &r
);
286 talloc_free(mem_ctx
);
288 if (!NT_STATUS_IS_OK(status
)) {
289 DEBUG(1, ("QueryInfoKey failed - %s\n", nt_errstr(status
)));
290 return ntstatus_to_werror(status
);
293 if (W_ERROR_IS_OK(r
.out
.result
)) {
294 mykeydata
->num_subkeys
= r
.out
.num_subkeys
;
295 mykeydata
->num_values
= r
.out
.num_values
;
296 mykeydata
->max_valnamelen
= r
.out
.max_valnamelen
;
297 mykeydata
->max_valdatalen
= r
.out
.max_valbufsize
;
303 static WERROR
rpc_del_key(const struct registry_key
*parent
, const char *name
)
306 struct rpc_key_data
*mykeydata
= parent
->backend_data
;
307 struct winreg_DeleteKey r
;
308 TALLOC_CTX
*mem_ctx
= talloc_init("del_key");
310 r
.in
.handle
= &mykeydata
->pol
;
311 init_winreg_String(&r
.in
.key
, name
);
313 status
= dcerpc_winreg_DeleteKey((struct dcerpc_pipe
*)parent
->hive
->backend_data
, mem_ctx
, &r
);
315 talloc_free(mem_ctx
);
320 static WERROR
rpc_num_values(const struct registry_key
*key
, uint32_t *count
)
322 struct rpc_key_data
*mykeydata
= key
->backend_data
;
325 if(mykeydata
->num_values
== -1) {
326 error
= rpc_query_key(key
);
327 if(!W_ERROR_IS_OK(error
)) return error
;
330 *count
= mykeydata
->num_values
;
334 static WERROR
rpc_num_subkeys(const struct registry_key
*key
, uint32_t *count
)
336 struct rpc_key_data
*mykeydata
= key
->backend_data
;
339 if(mykeydata
->num_subkeys
== -1) {
340 error
= rpc_query_key(key
);
341 if(!W_ERROR_IS_OK(error
)) return error
;
344 *count
= mykeydata
->num_subkeys
;
348 static struct hive_operations reg_backend_rpc
= {
350 .open_key
= rpc_open_key
,
351 .get_subkey_by_index
= rpc_get_subkey_by_index
,
352 .get_value_by_index
= rpc_get_value_by_index
,
353 .add_key
= rpc_add_key
,
354 .del_key
= rpc_del_key
,
355 .num_subkeys
= rpc_num_subkeys
,
356 .num_values
= rpc_num_values
,
359 _PUBLIC_ WERROR
reg_open_remote(struct registry_context
**ctx
, struct cli_credentials
*credentials
,
360 const char *location
, struct event_context
*ev
)
363 struct dcerpc_pipe
*p
;
365 *ctx
= talloc(NULL
, struct registry_context
);
367 /* Default to local smbd if no connection is specified */
369 location
= talloc_strdup(ctx
, "ncalrpc:");
372 status
= dcerpc_pipe_connect(*ctx
/* TALLOC_CTX */,
374 &dcerpc_table_winreg
,
376 (*ctx
)->backend_data
= p
;
378 if(NT_STATUS_IS_ERR(status
)) {
379 DEBUG(1, ("Unable to open '%s': %s\n", location
, nt_errstr(status
)));
382 return ntstatus_to_werror(status
);
385 (*ctx
)->get_predefined_key
= rpc_get_predefined_key
;
390 NTSTATUS
registry_rpc_init(void)
393 return registry_register(®_backend_rpc
);