2 * Samba Unix/Linux SMB client library
3 * Distributed SMB/CIFS Server Management Utility
4 * Local registry interface
6 * Copyright (C) Michael Adam 2008
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 "utils/net.h"
32 static void print_registry_key(const char *keyname
, NTTIME
*modtime
)
34 d_printf("Keyname = %s\n", keyname
);
35 d_printf("Modtime = %s\n",
37 ? http_timestring(nt_time_to_unix(*modtime
))
42 static void print_registry_value(const char *valname
,
43 const struct registry_value
*valvalue
)
45 d_printf("Valuename = %s\n", valname
);
46 d_printf("Type = %s\n",
47 reg_type_lookup(valvalue
->type
));
48 switch(valvalue
->type
) {
50 d_printf("Value = %d\n", valvalue
->v
.dword
);
54 d_printf("Value = \"%s\"\n", valvalue
->v
.sz
.str
);
58 for (j
= 0; j
< valvalue
->v
.multi_sz
.num_strings
; j
++) {
59 d_printf("Value[%3.3d] = \"%s\"\n", j
,
60 valvalue
->v
.multi_sz
.strings
[j
]);
65 d_printf("Value = %d bytes\n",
66 (int)valvalue
->v
.binary
.length
);
69 d_printf("Value = <unprintable>\n");
76 * Split path into hive name and subkeyname
77 * normalizations performed:
78 * - convert '/' to '\\'
79 * - strip trailing '\\' chars
81 static WERROR
split_hive_key(TALLOC_CTX
*ctx
, const char *path
,
82 char **hivename
, const char **subkeyname
)
86 if ((path
== NULL
) || (hivename
== NULL
) || (subkeyname
== NULL
)) {
87 return WERR_INVALID_PARAM
;
90 if (strlen(path
) == 0) {
91 return WERR_INVALID_PARAM
;
94 *hivename
= talloc_string_sub(ctx
, path
, "/", "\\");
95 if (*hivename
== NULL
) {
99 /* strip trailing '\\' chars */
100 p
= strrchr(*hivename
, '\\');
101 while ((p
!= NULL
) && (p
[1] == '\0')) {
103 p
= strrchr(*hivename
, '\\');
106 p
= strchr(*hivename
, '\\');
108 if ((p
== NULL
) || (*p
== '\0')) {
109 /* just the hive - no subkey given */
120 * split given path into hive and remaining path and open the hive key
122 static WERROR
open_hive(TALLOC_CTX
*ctx
, const char *path
,
123 uint32 desired_access
,
124 struct registry_key
**hive
,
128 NT_USER_TOKEN
*token
= NULL
;
129 char *hivename
= NULL
;
130 const char *tmp_subkeyname
= NULL
;
131 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
133 if ((hive
== NULL
) || (subkeyname
== NULL
)) {
134 werr
= WERR_INVALID_PARAM
;
138 werr
= split_hive_key(tmp_ctx
, path
, &hivename
, &tmp_subkeyname
);
139 if (!W_ERROR_IS_OK(werr
)) {
142 *subkeyname
= talloc_strdup(ctx
, tmp_subkeyname
);
143 if (*subkeyname
== NULL
) {
148 werr
= ntstatus_to_werror(registry_create_admin_token(tmp_ctx
, &token
));
149 if (!W_ERROR_IS_OK(werr
)) {
153 werr
= reg_openhive(ctx
, hivename
, desired_access
, token
, hive
);
154 if (!W_ERROR_IS_OK(werr
)) {
161 TALLOC_FREE(tmp_ctx
);
165 static WERROR
open_key(TALLOC_CTX
*ctx
, const char *path
,
166 uint32 desired_access
,
167 struct registry_key
**key
)
170 char *subkey_name
= NULL
;
171 struct registry_key
*hive
= NULL
;
172 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
174 if ((path
== NULL
) || (key
== NULL
)) {
175 return WERR_INVALID_PARAM
;
178 werr
= open_hive(tmp_ctx
, path
, desired_access
, &hive
, &subkey_name
);
179 if (!W_ERROR_IS_OK(werr
)) {
180 d_fprintf(stderr
, "open_hive failed: %s\n", dos_errstr(werr
));
184 werr
= reg_openkey(ctx
, hive
, subkey_name
, desired_access
, key
);
185 if (!W_ERROR_IS_OK(werr
)) {
186 d_fprintf(stderr
, "reg_openkey failed: %s\n",
194 TALLOC_FREE(tmp_ctx
);
200 * the main "net registry" function implementations
204 static int net_registry_enumerate(int argc
, const char **argv
)
207 struct registry_key
*key
= NULL
;
208 TALLOC_CTX
*ctx
= talloc_stackframe();
212 char *valname
= NULL
;
213 struct registry_value
*valvalue
= NULL
;
217 d_printf("Usage: net registry enumerate <path>\n");
218 d_printf("Example: net registry enumerate "
219 "'HKLM\\Software\\Samba'\n");
223 werr
= open_key(ctx
, argv
[0], REG_KEY_READ
, &key
);
224 if (!W_ERROR_IS_OK(werr
)) {
225 d_fprintf(stderr
, "open_key failed: %s\n", dos_errstr(werr
));
230 werr
= reg_enumkey(ctx
, key
, count
, &subkey_name
, modtime
),
234 print_registry_key(subkey_name
, modtime
);
236 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
241 werr
= reg_enumvalue(ctx
, key
, count
, &valname
, &valvalue
),
245 print_registry_value(valname
, valvalue
);
247 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS
, werr
)) {
257 static int net_registry_createkey(int argc
, const char **argv
)
260 enum winreg_CreateAction action
;
262 struct registry_key
*hivekey
= NULL
;
263 struct registry_key
*subkey
= NULL
;
264 TALLOC_CTX
*ctx
= talloc_stackframe();
268 d_printf("Usage: net registry createkey <path>\n");
269 d_printf("Example: net registry createkey "
270 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n");
273 if (strlen(argv
[0]) == 0) {
274 d_fprintf(stderr
, "error: zero length key name given\n");
278 werr
= open_hive(ctx
, argv
[0], REG_KEY_WRITE
, &hivekey
, &subkeyname
);
279 if (!W_ERROR_IS_OK(werr
)) {
280 d_fprintf(stderr
, "open_hive failed: %s\n", dos_errstr(werr
));
284 werr
= reg_createkey(ctx
, hivekey
, subkeyname
, REG_KEY_WRITE
,
286 if (!W_ERROR_IS_OK(werr
)) {
287 d_fprintf(stderr
, "reg_createkey failed: %s\n",
292 case REG_ACTION_NONE
:
293 d_printf("createkey did nothing -- huh?\n");
295 case REG_CREATED_NEW_KEY
:
296 d_printf("createkey created %s\n", argv
[0]);
298 case REG_OPENED_EXISTING_KEY
:
299 d_printf("createkey opened existing %s\n", argv
[0]);
310 static int net_registry_deletekey(int argc
, const char **argv
)
314 struct registry_key
*hivekey
= NULL
;
315 TALLOC_CTX
*ctx
= talloc_stackframe();
319 d_printf("Usage: net registry deletekey <path>\n");
320 d_printf("Example: net registry deletekey "
321 "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n");
324 if (strlen(argv
[0]) == 0) {
325 d_fprintf(stderr
, "error: zero length key name given\n");
329 werr
= open_hive(ctx
, argv
[0], REG_KEY_WRITE
, &hivekey
, &subkeyname
);
330 if (!W_ERROR_IS_OK(werr
)) {
331 d_fprintf(stderr
, "open_hive failed: %s\n", dos_errstr(werr
));
335 werr
= reg_deletekey(hivekey
, subkeyname
);
336 if (!W_ERROR_IS_OK(werr
)) {
337 d_fprintf(stderr
, "reg_deletekey failed: %s\n",
349 static int net_registry_setvalue(int argc
, const char **argv
)
352 struct registry_value value
;
353 struct registry_key
*key
= NULL
;
355 TALLOC_CTX
*ctx
= talloc_stackframe();
358 d_fprintf(stderr
, "usage: net rpc registry setvalue <key> "
359 "<valuename> <type> [<val>]+\n");
363 if (!strequal(argv
[2], "multi_sz") && (argc
!= 4)) {
364 d_fprintf(stderr
, "Too many args for type %s\n", argv
[2]);
368 if (strequal(argv
[2], "dword")) {
369 value
.type
= REG_DWORD
;
370 value
.v
.dword
= strtoul(argv
[3], NULL
, 10);
371 } else if (strequal(argv
[2], "sz")) {
373 value
.v
.sz
.len
= strlen(argv
[3])+1;
374 value
.v
.sz
.str
= CONST_DISCARD(char *, argv
[3]);
376 d_fprintf(stderr
, "type \"%s\" not implemented\n", argv
[2]);
380 werr
= open_key(ctx
, argv
[0], REG_KEY_WRITE
, &key
);
381 if (!W_ERROR_IS_OK(werr
)) {
382 d_fprintf(stderr
, "open_key failed: %s\n", dos_errstr(werr
));
386 werr
= reg_setvalue(key
, argv
[1], &value
);
387 if (!W_ERROR_IS_OK(werr
)) {
388 d_fprintf(stderr
, "reg_setvalue failed: %s\n",
400 static int net_registry_deletevalue(int argc
, const char **argv
)
403 struct registry_key
*key
= NULL
;
404 TALLOC_CTX
*ctx
= talloc_stackframe();
408 d_fprintf(stderr
, "usage: net rpc registry deletevalue <key> "
413 werr
= open_key(ctx
, argv
[0], REG_KEY_WRITE
, &key
);
414 if (!W_ERROR_IS_OK(werr
)) {
415 d_fprintf(stderr
, "open_key failed: %s\n", dos_errstr(werr
));
419 werr
= reg_deletevalue(key
, argv
[1]);
420 if (!W_ERROR_IS_OK(werr
)) {
421 d_fprintf(stderr
, "reg_deletekey failed: %s\n",
433 static int net_registry_getsd(int argc
, const char **argv
)
437 struct registry_key
*key
= NULL
;
438 struct security_descriptor
*secdesc
= NULL
;
439 TALLOC_CTX
*ctx
= talloc_stackframe();
440 uint32_t access_mask
= REG_KEY_READ
|
441 SEC_RIGHT_MAXIMUM_ALLOWED
|
442 SEC_RIGHT_SYSTEM_SECURITY
;
445 * net_rpc_regsitry uses SEC_RIGHT_SYSTEM_SECURITY, but access
446 * is denied with these perms right now...
448 access_mask
= REG_KEY_READ
;
451 d_printf("Usage: net registry getsd <path>\n");
452 d_printf("Example: net registry getsd "
453 "'HKLM\\Software\\Samba'\n");
456 if (strlen(argv
[0]) == 0) {
457 d_fprintf(stderr
, "error: zero length key name given\n");
461 werr
= open_key(ctx
, argv
[0], access_mask
, &key
);
462 if (!W_ERROR_IS_OK(werr
)) {
463 d_fprintf(stderr
, "open_key failed: %s\n", dos_errstr(werr
));
467 werr
= reg_getkeysecurity(ctx
, key
, &secdesc
);
468 if (!W_ERROR_IS_OK(werr
)) {
469 d_fprintf(stderr
, "reg_getkeysecurity failed: %s\n",
474 display_sec_desc(secdesc
);
483 int net_registry(int argc
, const char **argv
)
487 struct functable2 func
[] = {
490 net_registry_enumerate
,
491 "Enumerate registry keys and values"
495 net_registry_createkey
,
496 "Create a new registry key"
500 net_registry_deletekey
,
501 "Delete a registry key"
505 net_registry_setvalue
,
506 "Set a new registry value"
510 net_registry_deletevalue
,
511 "Delete a registry value"
516 "Get security descriptor"
521 if (!registry_init_basic()) {
525 ret
= net_run_function2(argc
, argv
, "net registry", func
);