Merge branch 'master' of ssh://git.samba.org/data/git/samba
[samba.git] / source3 / utils / net_registry.c
1 /*
2  * Samba Unix/Linux SMB client library
3  * Distributed SMB/CIFS Server Management Utility
4  * Local registry interface
5  *
6  * Copyright (C) Michael Adam 2008
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 "utils/net.h"
24 #include "utils/net_registry_util.h"
25
26
27 /*
28  *
29  * Helper functions
30  *
31  */
32
33 /**
34  * split given path into hive and remaining path and open the hive key
35  */
36 static WERROR open_hive(TALLOC_CTX *ctx, const char *path,
37                         uint32 desired_access,
38                         struct registry_key **hive,
39                         char **subkeyname)
40 {
41         WERROR werr;
42         NT_USER_TOKEN *token = NULL;
43         char *hivename = NULL;
44         char *tmp_subkeyname = NULL;
45         TALLOC_CTX *tmp_ctx = talloc_stackframe();
46
47         if ((hive == NULL) || (subkeyname == NULL)) {
48                 werr = WERR_INVALID_PARAM;
49                 goto done;
50         }
51
52         werr = split_hive_key(tmp_ctx, path, &hivename, &tmp_subkeyname);
53         if (!W_ERROR_IS_OK(werr)) {
54                 goto done;
55         }
56         *subkeyname = talloc_strdup(ctx, tmp_subkeyname);
57         if (*subkeyname == NULL) {
58                 werr = WERR_NOMEM;
59                 goto done;
60         }
61
62         werr = ntstatus_to_werror(registry_create_admin_token(tmp_ctx, &token));
63         if (!W_ERROR_IS_OK(werr)) {
64                 goto done;
65         }
66
67         werr = reg_openhive(ctx, hivename, desired_access, token, hive);
68         if (!W_ERROR_IS_OK(werr)) {
69                 goto done;
70         }
71
72         werr = WERR_OK;
73
74 done:
75         TALLOC_FREE(tmp_ctx);
76         return werr;
77 }
78
79 static WERROR open_key(TALLOC_CTX *ctx, const char *path,
80                        uint32 desired_access,
81                        struct registry_key **key)
82 {
83         WERROR werr;
84         char *subkey_name = NULL;
85         struct registry_key *hive = NULL;
86         TALLOC_CTX *tmp_ctx = talloc_stackframe();
87
88         if ((path == NULL) || (key == NULL)) {
89                 return WERR_INVALID_PARAM;
90         }
91
92         werr = open_hive(tmp_ctx, path, desired_access, &hive, &subkey_name);
93         if (!W_ERROR_IS_OK(werr)) {
94                 d_fprintf(stderr, "open_hive failed: %s\n", win_errstr(werr));
95                 goto done;
96         }
97
98         werr = reg_openkey(ctx, hive, subkey_name, desired_access, key);
99         if (!W_ERROR_IS_OK(werr)) {
100                 d_fprintf(stderr, "reg_openkey failed: %s\n",
101                           win_errstr(werr));
102                 goto done;
103         }
104
105         werr = WERR_OK;
106
107 done:
108         TALLOC_FREE(tmp_ctx);
109         return werr;
110 }
111
112 /*
113  *
114  * the main "net registry" function implementations
115  *
116  */
117
118 static int net_registry_enumerate(struct net_context *c, int argc,
119                                   const char **argv)
120 {
121         WERROR werr;
122         struct registry_key *key = NULL;
123         TALLOC_CTX *ctx = talloc_stackframe();
124         char *subkey_name;
125         NTTIME modtime;
126         uint32_t count;
127         char *valname = NULL;
128         struct registry_value *valvalue = NULL;
129         int ret = -1;
130
131         if (argc != 1 || c->display_usage) {
132                 d_printf("Usage:    net registry enumerate <path>\n");
133                 d_printf("Example:  net registry enumerate "
134                          "'HKLM\\Software\\Samba'\n");
135                 goto done;
136         }
137
138         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
139         if (!W_ERROR_IS_OK(werr)) {
140                 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
141                 goto done;
142         }
143
144         for (count = 0;
145              werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
146              W_ERROR_IS_OK(werr);
147              count++)
148         {
149                 print_registry_key(subkey_name, &modtime);
150         }
151         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
152                 goto done;
153         }
154
155         for (count = 0;
156              werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
157              W_ERROR_IS_OK(werr);
158              count++)
159         {
160                 print_registry_value_with_name(valname, valvalue);
161         }
162         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
163                 goto done;
164         }
165
166         ret = 0;
167 done:
168         TALLOC_FREE(ctx);
169         return ret;
170 }
171
172 static int net_registry_createkey(struct net_context *c, int argc,
173                                   const char **argv)
174 {
175         WERROR werr;
176         enum winreg_CreateAction action;
177         char *subkeyname;
178         struct registry_key *hivekey = NULL;
179         struct registry_key *subkey = NULL;
180         TALLOC_CTX *ctx = talloc_stackframe();
181         int ret = -1;
182
183         if (argc != 1 || c->display_usage) {
184                 d_printf("Usage:    net registry createkey <path>\n");
185                 d_printf("Example:  net registry createkey "
186                          "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n");
187                 goto done;
188         }
189         if (strlen(argv[0]) == 0) {
190                 d_fprintf(stderr, "error: zero length key name given\n");
191                 goto done;
192         }
193
194         werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
195         if (!W_ERROR_IS_OK(werr)) {
196                 d_fprintf(stderr, "open_hive failed: %s\n", win_errstr(werr));
197                 goto done;
198         }
199
200         werr = reg_createkey(ctx, hivekey, subkeyname, REG_KEY_WRITE,
201                              &subkey, &action);
202         if (!W_ERROR_IS_OK(werr)) {
203                 d_fprintf(stderr, "reg_createkey failed: %s\n",
204                           win_errstr(werr));
205                 goto done;
206         }
207         switch (action) {
208                 case REG_ACTION_NONE:
209                         d_printf("createkey did nothing -- huh?\n");
210                         break;
211                 case REG_CREATED_NEW_KEY:
212                         d_printf("createkey created %s\n", argv[0]);
213                         break;
214                 case REG_OPENED_EXISTING_KEY:
215                         d_printf("createkey opened existing %s\n", argv[0]);
216                         break;
217         }
218
219         ret = 0;
220
221 done:
222         TALLOC_FREE(ctx);
223         return ret;
224 }
225
226 static int net_registry_deletekey(struct net_context *c, int argc,
227                                   const char **argv)
228 {
229         WERROR werr;
230         char *subkeyname;
231         struct registry_key *hivekey = NULL;
232         TALLOC_CTX *ctx = talloc_stackframe();
233         int ret = -1;
234
235         if (argc != 1 || c->display_usage) {
236                 d_printf("Usage:    net registry deletekey <path>\n");
237                 d_printf("Example:  net registry deletekey "
238                          "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n");
239                 goto done;
240         }
241         if (strlen(argv[0]) == 0) {
242                 d_fprintf(stderr, "error: zero length key name given\n");
243                 goto done;
244         }
245
246         werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
247         if (!W_ERROR_IS_OK(werr)) {
248                 d_fprintf(stderr, "open_hive failed: %s\n", win_errstr(werr));
249                 goto done;
250         }
251
252         werr = reg_deletekey(hivekey, subkeyname);
253         if (!W_ERROR_IS_OK(werr)) {
254                 d_fprintf(stderr, "reg_deletekey failed: %s\n",
255                           win_errstr(werr));
256                 goto done;
257         }
258
259         ret = 0;
260
261 done:
262         TALLOC_FREE(ctx);
263         return ret;
264 }
265
266 static int net_registry_getvalue_internal(struct net_context *c, int argc,
267                                           const char **argv, bool raw)
268 {
269         WERROR werr;
270         int ret = -1;
271         struct registry_key *key = NULL;
272         struct registry_value *value = NULL;
273         TALLOC_CTX *ctx = talloc_stackframe();
274
275         if (argc != 2 || c->display_usage) {
276                 d_fprintf(stderr, "usage: net rpc registry getvalue <key> "
277                                   "<valuename>\n");
278                 goto done;
279         }
280
281         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
282         if (!W_ERROR_IS_OK(werr)) {
283                 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
284                 goto done;
285         }
286
287         werr = reg_queryvalue(ctx, key, argv[1], &value);
288         if (!W_ERROR_IS_OK(werr)) {
289                 d_fprintf(stderr, "reg_queryvalue failed: %s\n",
290                           win_errstr(werr));
291                 goto done;
292         }
293
294         print_registry_value(value, raw);
295
296         ret = 0;
297
298 done:
299         TALLOC_FREE(ctx);
300         return ret;
301 }
302
303 static int net_registry_getvalue(struct net_context *c, int argc,
304                                  const char **argv)
305 {
306         return net_registry_getvalue_internal(c, argc, argv, false);
307 }
308
309 static int net_registry_getvalueraw(struct net_context *c, int argc,
310                                     const char **argv)
311 {
312         return net_registry_getvalue_internal(c, argc, argv, true);
313 }
314
315 static int net_registry_setvalue(struct net_context *c, int argc,
316                                  const char **argv)
317 {
318         WERROR werr;
319         struct registry_value value;
320         struct registry_key *key = NULL;
321         int ret = -1;
322         TALLOC_CTX *ctx = talloc_stackframe();
323
324         if (argc < 4 || c->display_usage) {
325                 d_fprintf(stderr, "usage: net rpc registry setvalue <key> "
326                           "<valuename> <type> [<val>]+\n");
327                 goto done;
328         }
329
330         if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
331                 d_fprintf(stderr, "Too many args for type %s\n", argv[2]);
332                 goto done;
333         }
334
335         if (strequal(argv[2], "dword")) {
336                 value.type = REG_DWORD;
337                 value.v.dword = strtoul(argv[3], NULL, 10);
338         } else if (strequal(argv[2], "sz")) {
339                 value.type = REG_SZ;
340                 value.v.sz.len = strlen(argv[3])+1;
341                 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
342         } else if (strequal(argv[2], "multi_sz")) {
343                 value.type = REG_MULTI_SZ;
344                 value.v.multi_sz.num_strings = argc - 3;
345                 value.v.multi_sz.strings = (char **)(argv + 3);
346         } else {
347                 d_fprintf(stderr, "type \"%s\" not implemented\n", argv[2]);
348                 goto done;
349         }
350
351         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
352         if (!W_ERROR_IS_OK(werr)) {
353                 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
354                 goto done;
355         }
356
357         werr = reg_setvalue(key, argv[1], &value);
358         if (!W_ERROR_IS_OK(werr)) {
359                 d_fprintf(stderr, "reg_setvalue failed: %s\n",
360                           win_errstr(werr));
361                 goto done;
362         }
363
364         ret = 0;
365
366 done:
367         TALLOC_FREE(ctx);
368         return ret;
369 }
370
371 static int net_registry_deletevalue(struct net_context *c, int argc,
372                                     const char **argv)
373 {
374         WERROR werr;
375         struct registry_key *key = NULL;
376         TALLOC_CTX *ctx = talloc_stackframe();
377         int ret = -1;
378
379         if (argc != 2 || c->display_usage) {
380                 d_fprintf(stderr, "usage: net rpc registry deletevalue <key> "
381                           "<valuename>\n");
382                 goto done;
383         }
384
385         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
386         if (!W_ERROR_IS_OK(werr)) {
387                 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
388                 goto done;
389         }
390
391         werr = reg_deletevalue(key, argv[1]);
392         if (!W_ERROR_IS_OK(werr)) {
393                 d_fprintf(stderr, "reg_deletekey failed: %s\n",
394                           win_errstr(werr));
395                 goto done;
396         }
397
398         ret = 0;
399
400 done:
401         TALLOC_FREE(ctx);
402         return ret;
403 }
404
405 static int net_registry_getsd(struct net_context *c, int argc,
406                               const char **argv)
407 {
408         WERROR werr;
409         int ret = -1;
410         struct registry_key *key = NULL;
411         struct security_descriptor *secdesc = NULL;
412         TALLOC_CTX *ctx = talloc_stackframe();
413         uint32_t access_mask = REG_KEY_READ |
414                                SEC_RIGHT_MAXIMUM_ALLOWED |
415                                SEC_RIGHT_SYSTEM_SECURITY;
416
417         /*
418          * net_rpc_regsitry uses SEC_RIGHT_SYSTEM_SECURITY, but access
419          * is denied with these perms right now...
420          */
421         access_mask = REG_KEY_READ;
422
423         if (argc != 1 || c->display_usage) {
424                 d_printf("Usage:    net registry getsd <path>\n");
425                 d_printf("Example:  net registry getsd "
426                          "'HKLM\\Software\\Samba'\n");
427                 goto done;
428         }
429         if (strlen(argv[0]) == 0) {
430                 d_fprintf(stderr, "error: zero length key name given\n");
431                 goto done;
432         }
433
434         werr = open_key(ctx, argv[0], access_mask, &key);
435         if (!W_ERROR_IS_OK(werr)) {
436                 d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr));
437                 goto done;
438         }
439
440         werr = reg_getkeysecurity(ctx, key, &secdesc);
441         if (!W_ERROR_IS_OK(werr)) {
442                 d_fprintf(stderr, "reg_getkeysecurity failed: %s\n",
443                           win_errstr(werr));
444                 goto done;
445         }
446
447         display_sec_desc(secdesc);
448
449         ret = 0;
450
451 done:
452         TALLOC_FREE(ctx);
453         return ret;
454 }
455
456 int net_registry(struct net_context *c, int argc, const char **argv)
457 {
458         int ret = -1;
459
460         struct functable func[] = {
461                 {
462                         "enumerate",
463                         net_registry_enumerate,
464                         NET_TRANSPORT_LOCAL,
465                         "Enumerate registry keys and values",
466                         "net registry enumerate\n"
467                         "    Enumerate registry keys and values"
468                 },
469                 {
470                         "createkey",
471                         net_registry_createkey,
472                         NET_TRANSPORT_LOCAL,
473                         "Create a new registry key",
474                         "net registry createkey\n"
475                         "    Create a new registry key"
476                 },
477                 {
478                         "deletekey",
479                         net_registry_deletekey,
480                         NET_TRANSPORT_LOCAL,
481                         "Delete a registry key",
482                         "net registry deletekey\n"
483                         "    Delete a registry key"
484                 },
485                 {
486                         "getvalue",
487                         net_registry_getvalue,
488                         NET_TRANSPORT_LOCAL,
489                         "Print a registry value",
490                         "net registry getvalue\n"
491                         "    Print a registry value"
492                 },
493                 {
494                         "getvalueraw",
495                         net_registry_getvalueraw,
496                         NET_TRANSPORT_LOCAL,
497                         "Print a registry value (raw format)",
498                         "net registry getvalueraw\n"
499                         "    Print a registry value (raw format)"
500                 },
501                 {
502                         "setvalue",
503                         net_registry_setvalue,
504                         NET_TRANSPORT_LOCAL,
505                         "Set a new registry value",
506                         "net registry setvalue\n"
507                         "    Set a new registry value"
508                 },
509                 {
510                         "deletevalue",
511                         net_registry_deletevalue,
512                         NET_TRANSPORT_LOCAL,
513                         "Delete a registry value",
514                         "net registry deletevalue\n"
515                         "    Delete a registry value"
516                 },
517                 {
518                         "getsd",
519                         net_registry_getsd,
520                         NET_TRANSPORT_LOCAL,
521                         "Get security descriptor",
522                         "net registry getsd\n"
523                         "    Get security descriptor"
524                 },
525         { NULL, NULL, 0, NULL, NULL }
526         };
527
528         if (!W_ERROR_IS_OK(registry_init_basic())) {
529                 return -1;
530         }
531
532         ret = net_run_function(c, argc, argv, "net registry", func);
533
534         return ret;
535 }