Fix a segfault (an uninitialized variable)
[Samba.git] / source / utils / net_registry.c
blob3d245007749f8292463917d368b482e476be552d
1 /*
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/>.
22 #include "includes.h"
23 #include "utils/net.h"
28 * Helper functions
32 static void print_registry_key(const char *keyname, NTTIME *modtime)
34 d_printf("Keyname = %s\n", keyname);
35 d_printf("Modtime = %s\n",
36 modtime
37 ? http_timestring(nt_time_to_unix(*modtime))
38 : "None");
39 d_printf("\n");
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) {
49 case REG_DWORD:
50 d_printf("Value = %d\n", valvalue->v.dword);
51 break;
52 case REG_SZ:
53 case REG_EXPAND_SZ:
54 d_printf("Value = \"%s\"\n", valvalue->v.sz.str);
55 break;
56 case REG_MULTI_SZ: {
57 uint32 j;
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]);
62 break;
64 case REG_BINARY:
65 d_printf("Value = %d bytes\n",
66 (int)valvalue->v.binary.length);
67 break;
68 default:
69 d_printf("Value = <unprintable>\n");
70 break;
72 d_printf("\n");
75 /**
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)
84 char *p;
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) {
96 return WERR_NOMEM;
99 /* strip trailing '\\' chars */
100 p = strrchr(*hivename, '\\');
101 while ((p != NULL) && (p[1] == '\0')) {
102 *p = '\0';
103 p = strrchr(*hivename, '\\');
106 p = strchr(*hivename, '\\');
108 if ((p == NULL) || (*p == '\0')) {
109 /* just the hive - no subkey given */
110 *subkeyname = "";
111 } else {
112 *p = '\0';
113 *subkeyname = p+1;
116 return WERR_OK;
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,
125 char **subkeyname)
127 WERROR werr;
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;
135 goto done;
138 werr = split_hive_key(tmp_ctx, path, &hivename, &tmp_subkeyname);
139 if (!W_ERROR_IS_OK(werr)) {
140 goto done;
142 *subkeyname = talloc_strdup(ctx, tmp_subkeyname);
143 if (*subkeyname == NULL) {
144 werr = WERR_NOMEM;
145 goto done;
148 werr = ntstatus_to_werror(registry_create_admin_token(tmp_ctx, &token));
149 if (!W_ERROR_IS_OK(werr)) {
150 goto done;
153 werr = reg_openhive(ctx, hivename, desired_access, token, hive);
154 if (!W_ERROR_IS_OK(werr)) {
155 goto done;
158 werr = WERR_OK;
160 done:
161 TALLOC_FREE(tmp_ctx);
162 return werr;
165 static WERROR open_key(TALLOC_CTX *ctx, const char *path,
166 uint32 desired_access,
167 struct registry_key **key)
169 WERROR werr;
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));
181 goto done;
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",
187 dos_errstr(werr));
188 goto done;
191 werr = WERR_OK;
193 done:
194 TALLOC_FREE(tmp_ctx);
195 return werr;
200 * the main "net registry" function implementations
204 static int net_registry_enumerate(int argc, const char **argv)
206 WERROR werr;
207 struct registry_key *key = NULL;
208 TALLOC_CTX *ctx = talloc_stackframe();
209 char *subkey_name;
210 NTTIME modtime;
211 uint32_t count;
212 char *valname = NULL;
213 struct registry_value *valvalue = NULL;
214 int ret = -1;
216 if (argc != 1) {
217 d_printf("Usage: net registry enumerate <path>\n");
218 d_printf("Example: net registry enumerate "
219 "'HKLM\\Software\\Samba'\n");
220 goto done;
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));
226 goto done;
229 for (count = 0;
230 werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
231 W_ERROR_IS_OK(werr);
232 count++)
234 print_registry_key(subkey_name, &modtime);
236 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
237 goto done;
240 for (count = 0;
241 werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
242 W_ERROR_IS_OK(werr);
243 count++)
245 print_registry_value(valname, valvalue);
247 if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
248 goto done;
251 ret = 0;
252 done:
253 TALLOC_FREE(ctx);
254 return ret;
257 static int net_registry_createkey(int argc, const char **argv)
259 WERROR werr;
260 enum winreg_CreateAction action;
261 char *subkeyname;
262 struct registry_key *hivekey = NULL;
263 struct registry_key *subkey = NULL;
264 TALLOC_CTX *ctx = talloc_stackframe();
265 int ret = -1;
267 if (argc != 1) {
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");
271 goto done;
273 if (strlen(argv[0]) == 0) {
274 d_fprintf(stderr, "error: zero length key name given\n");
275 goto done;
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));
281 goto done;
284 werr = reg_createkey(ctx, hivekey, subkeyname, REG_KEY_WRITE,
285 &subkey, &action);
286 if (!W_ERROR_IS_OK(werr)) {
287 d_fprintf(stderr, "reg_createkey failed: %s\n",
288 dos_errstr(werr));
289 goto done;
291 switch (action) {
292 case REG_ACTION_NONE:
293 d_printf("createkey did nothing -- huh?\n");
294 break;
295 case REG_CREATED_NEW_KEY:
296 d_printf("createkey created %s\n", argv[0]);
297 break;
298 case REG_OPENED_EXISTING_KEY:
299 d_printf("createkey opened existing %s\n", argv[0]);
300 break;
303 ret = 0;
305 done:
306 TALLOC_FREE(ctx);
307 return ret;
310 static int net_registry_deletekey(int argc, const char **argv)
312 WERROR werr;
313 char *subkeyname;
314 struct registry_key *hivekey = NULL;
315 TALLOC_CTX *ctx = talloc_stackframe();
316 int ret = -1;
318 if (argc != 1) {
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");
322 goto done;
324 if (strlen(argv[0]) == 0) {
325 d_fprintf(stderr, "error: zero length key name given\n");
326 goto done;
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));
332 goto done;
335 werr = reg_deletekey(hivekey, subkeyname);
336 if (!W_ERROR_IS_OK(werr)) {
337 d_fprintf(stderr, "reg_deletekey failed: %s\n",
338 dos_errstr(werr));
339 goto done;
342 ret = 0;
344 done:
345 TALLOC_FREE(ctx);
346 return ret;
349 static int net_registry_setvalue(int argc, const char **argv)
351 WERROR werr;
352 struct registry_value value;
353 struct registry_key *key = NULL;
354 int ret = -1;
355 TALLOC_CTX *ctx = talloc_stackframe();
357 if (argc < 4) {
358 d_fprintf(stderr, "usage: net rpc registry setvalue <key> "
359 "<valuename> <type> [<val>]+\n");
360 goto done;
363 if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
364 d_fprintf(stderr, "Too many args for type %s\n", argv[2]);
365 goto done;
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")) {
372 value.type = REG_SZ;
373 value.v.sz.len = strlen(argv[3])+1;
374 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
375 } else {
376 d_fprintf(stderr, "type \"%s\" not implemented\n", argv[2]);
377 goto done;
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));
383 goto done;
386 werr = reg_setvalue(key, argv[1], &value);
387 if (!W_ERROR_IS_OK(werr)) {
388 d_fprintf(stderr, "reg_setvalue failed: %s\n",
389 dos_errstr(werr));
390 goto done;
393 ret = 0;
395 done:
396 TALLOC_FREE(ctx);
397 return ret;
400 static int net_registry_deletevalue(int argc, const char **argv)
402 WERROR werr;
403 struct registry_key *key = NULL;
404 TALLOC_CTX *ctx = talloc_stackframe();
405 int ret = -1;
407 if (argc != 2) {
408 d_fprintf(stderr, "usage: net rpc registry deletevalue <key> "
409 "<valuename>\n");
410 goto done;
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));
416 goto done;
419 werr = reg_deletevalue(key, argv[1]);
420 if (!W_ERROR_IS_OK(werr)) {
421 d_fprintf(stderr, "reg_deletekey failed: %s\n",
422 dos_errstr(werr));
423 goto done;
426 ret = 0;
428 done:
429 TALLOC_FREE(ctx);
430 return ret;
433 static int net_registry_getsd(int argc, const char **argv)
435 WERROR werr;
436 int ret = -1;
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;
450 if (argc != 1) {
451 d_printf("Usage: net registry getsd <path>\n");
452 d_printf("Example: net registry getsd "
453 "'HKLM\\Software\\Samba'\n");
454 goto done;
456 if (strlen(argv[0]) == 0) {
457 d_fprintf(stderr, "error: zero length key name given\n");
458 goto done;
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));
464 goto done;
467 werr = reg_getkeysecurity(ctx, key, &secdesc);
468 if (!W_ERROR_IS_OK(werr)) {
469 d_fprintf(stderr, "reg_getkeysecurity failed: %s\n",
470 dos_errstr(werr));
471 goto done;
474 display_sec_desc(secdesc);
476 ret = 0;
478 done:
479 TALLOC_FREE(ctx);
480 return ret;
483 int net_registry(int argc, const char **argv)
485 int ret = -1;
487 struct functable2 func[] = {
489 "enumerate",
490 net_registry_enumerate,
491 "Enumerate registry keys and values"
494 "createkey",
495 net_registry_createkey,
496 "Create a new registry key"
499 "deletekey",
500 net_registry_deletekey,
501 "Delete a registry key"
504 "setvalue",
505 net_registry_setvalue,
506 "Set a new registry value"
509 "deletevalue",
510 net_registry_deletevalue,
511 "Delete a registry value"
514 "getsd",
515 net_registry_getsd,
516 "Get security descriptor"
518 { NULL, NULL, NULL }
521 if (!registry_init_basic()) {
522 return -1;
525 ret = net_run_function2(argc, argv, "net registry", func);
527 regdb_close();
529 return ret;