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. */
21 #include "lib/registry/common/registry.h"
23 static void init_winreg_String(struct winreg_String
*name
, const char *s
)
27 name
->name_len
= 2 * (strlen_m(s
) + 1);
28 name
->name_size
= name
->name_len
;
36 #define openhive(u) static struct policy_handle *open_ ## u(struct dcerpc_pipe *p, REG_HANDLE *h) \
39 struct winreg_Open ## u r; \
40 struct winreg_OpenUnknown unknown; \
41 struct policy_handle *hnd = malloc(sizeof(struct policy_handle)); \
43 unknown.unknown0 = 0x84e0; \
44 unknown.unknown1 = 0x0000; \
45 r.in.unknown = &unknown; \
46 r.in.access_required = SEC_RIGHTS_MAXIMUM_ALLOWED; \
49 if (!NT_STATUS_IS_OK(dcerpc_winreg_Open ## u(p, h->mem_ctx, &r))) {\
50 DEBUG(0,("Error executing open\n"));\
64 struct dcerpc_pipe
*pipe
;
65 struct policy_handle
*hives
[10];
70 struct policy_handle
*(*open
) (struct dcerpc_pipe
*p
, REG_HANDLE
*h
);
72 { "HKEY_LOCAL_MACHINE", open_HKLM
},
73 { "HKEY_CURRENT_USER", open_HKCU
},
74 { "HKEY_CLASSES_ROOT", open_HKCR
},
75 { "HKEY_PERFORMANCE_DATA", open_HKPD
},
76 { "HKEY_USERS", open_HKU
},
80 static WERROR
rpc_open_registry(REG_HANDLE
*h
, const char *location
, const char *credentials
)
82 struct rpc_data
*mydata
= talloc(h
->mem_ctx
, sizeof(struct rpc_data
));
83 char *binding
= strdup(location
);
87 if(!credentials
|| !location
) return WERR_INVALID_PARAM
;
89 user
= talloc_strdup(h
->mem_ctx
, credentials
);
90 pass
= strchr(user
, '%');
95 status
= dcerpc_pipe_connect(&mydata
->pipe
, binding
,
97 DCERPC_WINREG_VERSION
,
102 h
->backend_data
= mydata
;
104 return ntstatus_to_werror(status
);
107 static WERROR
rpc_open_root(REG_HANDLE
*h
, REG_KEY
**k
)
109 /* There's not really a 'root' key here */
110 *k
= reg_key_new_abs("\\", h
, h
->backend_data
);
114 static WERROR
rpc_close_registry(REG_HANDLE
*h
)
116 dcerpc_pipe_close(((struct rpc_data
*)h
->backend_data
)->pipe
);
117 free(h
->backend_data
);
121 static struct policy_handle
*rpc_get_key_handle(REG_HANDLE
*h
, const char *path
)
125 struct rpc_data
*mydata
= h
->backend_data
;
126 struct policy_handle
*hive
= NULL
;
127 char *end
= strchr(path
+1, '\\');
129 struct winreg_OpenKey r
;
130 struct policy_handle
*key_handle
= talloc(h
->mem_ctx
, sizeof(struct policy_handle
));
133 if(end
) hivename
= strndup(path
+1, end
-path
-1);
134 else hivename
= strdup(path
+1);
136 for(i
= 0; known_hives
[i
].name
; i
++) {
137 if(!strcmp(hivename
, known_hives
[i
].name
)) {
138 if(!mydata
->hives
[i
]) mydata
->hives
[i
] = known_hives
[i
].open(mydata
->pipe
, h
);
139 hive
= mydata
->hives
[i
];
144 DEBUG(0, ("No such hive: %s\n", hivename
));
148 DEBUG(2, ("Opening %s, hive: %s\n", path
, hivename
));
150 if(!end
|| !(*end
) || !(*(end
+1))) return hive
;
152 memset(&r
, 0, sizeof(struct winreg_OpenKey
));
154 init_winreg_String(&r
.in
.keyname
, end
+1);
155 r
.in
.unknown
= 0x00000000;
156 r
.in
.access_mask
= 0x02000000;
157 r
.out
.handle
= key_handle
;
159 mem_ctx
= talloc_init("openkey");
160 status
= dcerpc_winreg_OpenKey(mydata
->pipe
, mem_ctx
, &r
);
161 talloc_destroy(mem_ctx
);
163 if (!NT_STATUS_IS_OK(status
) || !W_ERROR_IS_OK(r
.out
.result
)) {
170 static WERROR
rpc_open_key(REG_HANDLE
*h
, const char *name
, REG_KEY
**key
)
172 struct policy_handle
*pol
= rpc_get_key_handle(h
, name
);
173 if(!pol
) return WERR_DEST_NOT_FOUND
;
174 *key
= reg_key_new_abs(name
, h
, pol
);
178 static WERROR
rpc_fetch_subkeys(REG_KEY
*parent
, int *count
, REG_KEY
***subkeys
)
180 struct winreg_EnumKey r
;
181 struct winreg_EnumKeyNameRequest keyname
;
182 struct winreg_String classname
;
183 struct winreg_Time tm
;
184 struct rpc_data
*mydata
= parent
->handle
->backend_data
;
186 REG_KEY
**ar
= talloc(parent
->mem_ctx
, sizeof(REG_KEY
*));
187 NTSTATUS status
= NT_STATUS_OK
;
191 if(parent
->backend_data
== parent
->handle
->backend_data
) {
192 for(i
= 0; known_hives
[i
].name
; i
++) {
193 ar
[i
] = reg_key_new_rel(known_hives
[i
].name
, parent
, NULL
);
195 ar
= talloc_realloc(parent
->mem_ctx
, ar
, sizeof(REG_KEY
*) * ((*count
)+1));
203 if(!parent
->backend_data
) parent
->backend_data
= rpc_get_key_handle(parent
->handle
, reg_key_get_path(parent
));
205 if(!parent
->backend_data
) return WERR_GENERAL_FAILURE
;
208 r
.in
.handle
= parent
->backend_data
;
209 keyname
.unknown
= 0x0000020a;
210 init_winreg_String(&keyname
.key_name
, NULL
);
211 init_winreg_String(&classname
, NULL
);
212 r
.in
.in_name
= &keyname
;
213 r
.in
.class = &classname
;
214 tm
.low
= tm
.high
= 0x7fffffff;
215 r
.in
.last_changed_time
= &tm
;
218 for(i
= 0; NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(r
.out
.result
); i
++) {
220 r
.in
.unknown
= r
.out
.unknown
= 0x0414;
221 r
.in
.key_name_len
= r
.out
.key_name_len
= 0;
222 status
= dcerpc_winreg_EnumKey(mydata
->pipe
, parent
->mem_ctx
, &r
);
223 if(NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(r
.out
.result
)) {
224 ar
[(*count
)] = reg_key_new_rel(r
.out
.out_name
->name
, parent
, NULL
);
226 ar
= talloc_realloc(parent
->mem_ctx
, ar
, ((*count
)+1) * sizeof(REG_KEY
*));
234 static WERROR
rpc_fetch_values(REG_KEY
*parent
, int *count
, REG_VAL
***values
)
236 struct winreg_EnumValue r
;
237 struct winreg_Uint8buf value
;
238 struct winreg_String valuename
;
239 struct rpc_data
*mydata
= parent
->handle
->backend_data
;
241 uint32 type
, requested_len
, returned_len
;
242 NTSTATUS status
= NT_STATUS_OK
;
243 REG_VAL
**ar
= malloc(sizeof(REG_VAL
*));
248 if(parent
->backend_data
== parent
->handle
->backend_data
) {
253 if(!parent
->backend_data
) parent
->backend_data
= rpc_get_key_handle(parent
->handle
, reg_key_get_path(parent
));
255 if(!parent
->backend_data
) return WERR_GENERAL_FAILURE
;
257 r
.in
.handle
= parent
->backend_data
;
260 init_winreg_String(&valuename
, NULL
);
261 r
.in
.name
= r
.out
.name
= &valuename
;
264 r
.in
.type
= r
.out
.type
= &type
;
265 value
.max_len
= 0x7fff;
270 r
.in
.value
= r
.out
.value
= &value
;
272 requested_len
= value
.max_len
;
273 r
.in
.requested_len
= &requested_len
;
275 r
.in
.returned_len
= &returned_len
;
279 status
= dcerpc_winreg_EnumValue(mydata
->pipe
, parent
->mem_ctx
, &r
);
280 if(NT_STATUS_IS_OK(status
) && W_ERROR_IS_OK(r
.out
.result
)) {
282 ar
[(*count
)] = reg_val_new(parent
, NULL
);
283 ar
[(*count
)]->name
= talloc_strdup(ar
[*count
]->mem_ctx
, r
.out
.name
->name
);
284 ar
[(*count
)]->data_type
= *r
.out
.type
;
285 ar
[(*count
)]->data_len
= value
.len
;
286 ar
[(*count
)]->data_blk
= talloc(ar
[*count
]->mem_ctx
, value
.len
);
287 memcpy(ar
[(*count
)]->data_blk
, value
.buffer
, value
.len
);
289 ar
= talloc_realloc(parent
->mem_ctx
, ar
, ((*count
)+1) * sizeof(REG_VAL
*));
298 static WERROR
rpc_add_key(REG_KEY
*parent
, const char *name
)
301 return WERR_NOT_SUPPORTED
;
304 static struct policy_handle
*get_hive(REG_KEY
*k
)
307 struct rpc_data
*mydata
= k
->handle
->backend_data
;
308 for(i
= 0; known_hives
[i
].name
; i
++) {
309 if(!strncmp(known_hives
[i
].name
, reg_key_get_path(k
)+1, strlen(known_hives
[i
].name
)))
310 return mydata
->hives
[i
];
315 static WERROR
rpc_del_key(REG_KEY
*k
)
318 struct rpc_data
*mydata
= k
->handle
->backend_data
;
319 struct winreg_DeleteKey r
;
321 struct policy_handle
*hive
= get_hive(k
);
323 printf("first: %s\n", reg_key_get_path(k
));
324 hivepath
= strchr(reg_key_get_path(k
), '\\');
325 hivepath
= strchr(hivepath
+1, '\\');
326 printf("asfter: %s\n", hivepath
+1);
329 init_winreg_String(&r
.in
.key
, hivepath
+1);
331 status
= dcerpc_winreg_DeleteKey(mydata
->pipe
, k
->mem_ctx
, &r
);
336 static struct registry_ops reg_backend_rpc
= {
338 .open_registry
= rpc_open_registry
,
339 .close_registry
= rpc_close_registry
,
340 .open_root_key
= rpc_open_root
,
341 .open_key
= rpc_open_key
,
342 .fetch_subkeys
= rpc_fetch_subkeys
,
343 .fetch_values
= rpc_fetch_values
,
344 .add_key
= rpc_add_key
,
345 .del_key
= rpc_del_key
,
348 NTSTATUS
reg_rpc_init(void)
350 return register_backend("registry", ®_backend_rpc
);