s3:net: add i18n macro _() to one message
[mat/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"),
95                           win_errstr(werr));
96                 goto done;
97         }
98
99         werr = reg_openkey(ctx, hive, subkey_name, desired_access, key);
100         if (!W_ERROR_IS_OK(werr)) {
101                 d_fprintf(stderr, _("reg_openkey failed: %s\n"),
102                           win_errstr(werr));
103                 goto done;
104         }
105
106         werr = WERR_OK;
107
108 done:
109         TALLOC_FREE(tmp_ctx);
110         return werr;
111 }
112
113 /*
114  *
115  * the main "net registry" function implementations
116  *
117  */
118
119 static int net_registry_enumerate(struct net_context *c, int argc,
120                                   const char **argv)
121 {
122         WERROR werr;
123         struct registry_key *key = NULL;
124         TALLOC_CTX *ctx = talloc_stackframe();
125         char *subkey_name;
126         NTTIME modtime;
127         uint32_t count;
128         char *valname = NULL;
129         struct registry_value *valvalue = NULL;
130         int ret = -1;
131
132         if (argc != 1 || c->display_usage) {
133                 d_printf("%s\n%s",
134                          _("Usage:"),
135                          _("net registry enumerate <path>\n"));
136                 d_printf("%s\n%s",
137                          _("Example:"),
138                          _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
139                 goto done;
140         }
141
142         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
143         if (!W_ERROR_IS_OK(werr)) {
144                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
145                 goto done;
146         }
147
148         for (count = 0;
149              werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
150              W_ERROR_IS_OK(werr);
151              count++)
152         {
153                 print_registry_key(subkey_name, &modtime);
154         }
155         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
156                 goto done;
157         }
158
159         for (count = 0;
160              werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
161              W_ERROR_IS_OK(werr);
162              count++)
163         {
164                 print_registry_value_with_name(valname, valvalue);
165         }
166         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
167                 goto done;
168         }
169
170         ret = 0;
171 done:
172         TALLOC_FREE(ctx);
173         return ret;
174 }
175
176 static int net_registry_createkey(struct net_context *c, int argc,
177                                   const char **argv)
178 {
179         WERROR werr;
180         enum winreg_CreateAction action;
181         char *subkeyname;
182         struct registry_key *hivekey = NULL;
183         struct registry_key *subkey = NULL;
184         TALLOC_CTX *ctx = talloc_stackframe();
185         int ret = -1;
186
187         if (argc != 1 || c->display_usage) {
188                 d_printf("%s\n%s",
189                          _("Usage:"),
190                          _("net registry createkey <path>\n"));
191                 d_printf("%s\n%s",
192                          _("Example:"),
193                          _("net registry createkey "
194                            "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
195                 goto done;
196         }
197         if (strlen(argv[0]) == 0) {
198                 d_fprintf(stderr, _("error: zero length key name given\n"));
199                 goto done;
200         }
201
202         werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
203         if (!W_ERROR_IS_OK(werr)) {
204                 d_fprintf(stderr, _("open_hive failed: %s\n"),
205                           win_errstr(werr));
206                 goto done;
207         }
208
209         werr = reg_createkey(ctx, hivekey, subkeyname, REG_KEY_WRITE,
210                              &subkey, &action);
211         if (!W_ERROR_IS_OK(werr)) {
212                 d_fprintf(stderr, _("reg_createkey failed: %s\n"),
213                           win_errstr(werr));
214                 goto done;
215         }
216         switch (action) {
217                 case REG_ACTION_NONE:
218                         d_printf(_("createkey did nothing -- huh?\n"));
219                         break;
220                 case REG_CREATED_NEW_KEY:
221                         d_printf(_("createkey created %s\n"), argv[0]);
222                         break;
223                 case REG_OPENED_EXISTING_KEY:
224                         d_printf(_("createkey opened existing %s\n"), argv[0]);
225                         break;
226         }
227
228         ret = 0;
229
230 done:
231         TALLOC_FREE(ctx);
232         return ret;
233 }
234
235 static int net_registry_deletekey(struct net_context *c, int argc,
236                                   const char **argv)
237 {
238         WERROR werr;
239         char *subkeyname;
240         struct registry_key *hivekey = NULL;
241         TALLOC_CTX *ctx = talloc_stackframe();
242         int ret = -1;
243
244         if (argc != 1 || c->display_usage) {
245                 d_printf("%s\n%s",
246                          _("Usage:"),
247                          _("net registry deletekey <path>\n"));
248                 d_printf("%s\n%s",
249                          _("Example:"),
250                          _("net registry deletekey "
251                            "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
252                 goto done;
253         }
254         if (strlen(argv[0]) == 0) {
255                 d_fprintf(stderr, _("error: zero length key name given\n"));
256                 goto done;
257         }
258
259         werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
260         if (!W_ERROR_IS_OK(werr)) {
261                 d_fprintf(stderr, "open_hive %s: %s\n", _("failed"),
262                           win_errstr(werr));
263                 goto done;
264         }
265
266         werr = reg_deletekey(hivekey, subkeyname);
267         if (!W_ERROR_IS_OK(werr)) {
268                 d_fprintf(stderr, "reg_deletekey %s: %s\n", _("failed"),
269                           win_errstr(werr));
270                 goto done;
271         }
272
273         ret = 0;
274
275 done:
276         TALLOC_FREE(ctx);
277         return ret;
278 }
279
280 static int net_registry_getvalue_internal(struct net_context *c, int argc,
281                                           const char **argv, bool raw)
282 {
283         WERROR werr;
284         int ret = -1;
285         struct registry_key *key = NULL;
286         struct registry_value *value = NULL;
287         TALLOC_CTX *ctx = talloc_stackframe();
288
289         if (argc != 2 || c->display_usage) {
290                 d_fprintf(stderr, "%s\n%s",
291                           _("Usage:"),
292                           _("net rpc registry getvalue <key> <valuename>\n"));
293                 goto done;
294         }
295
296         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
297         if (!W_ERROR_IS_OK(werr)) {
298                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
299                 goto done;
300         }
301
302         werr = reg_queryvalue(ctx, key, argv[1], &value);
303         if (!W_ERROR_IS_OK(werr)) {
304                 d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
305                           win_errstr(werr));
306                 goto done;
307         }
308
309         print_registry_value(value, raw);
310
311         ret = 0;
312
313 done:
314         TALLOC_FREE(ctx);
315         return ret;
316 }
317
318 static int net_registry_getvalue(struct net_context *c, int argc,
319                                  const char **argv)
320 {
321         return net_registry_getvalue_internal(c, argc, argv, false);
322 }
323
324 static int net_registry_getvalueraw(struct net_context *c, int argc,
325                                     const char **argv)
326 {
327         return net_registry_getvalue_internal(c, argc, argv, true);
328 }
329
330 static int net_registry_setvalue(struct net_context *c, int argc,
331                                  const char **argv)
332 {
333         WERROR werr;
334         struct registry_value value;
335         struct registry_key *key = NULL;
336         int ret = -1;
337         TALLOC_CTX *ctx = talloc_stackframe();
338
339         if (argc < 4 || c->display_usage) {
340                 d_fprintf(stderr, "%s\n%s",
341                           _("Usage:"),
342                           _("net rpc registry setvalue <key> <valuename> "
343                             "<type> [<val>]+\n"));
344                 goto done;
345         }
346
347         if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
348                 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
349                 goto done;
350         }
351
352         if (strequal(argv[2], "dword")) {
353                 value.type = REG_DWORD;
354                 value.v.dword = strtoul(argv[3], NULL, 10);
355         } else if (strequal(argv[2], "sz")) {
356                 value.type = REG_SZ;
357                 value.v.sz.len = strlen(argv[3])+1;
358                 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
359         } else if (strequal(argv[2], "multi_sz")) {
360                 value.type = REG_MULTI_SZ;
361                 value.v.multi_sz.num_strings = argc - 3;
362                 value.v.multi_sz.strings = (char **)(argv + 3);
363         } else {
364                 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
365                 goto done;
366         }
367
368         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
369         if (!W_ERROR_IS_OK(werr)) {
370                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
371                 goto done;
372         }
373
374         werr = reg_setvalue(key, argv[1], &value);
375         if (!W_ERROR_IS_OK(werr)) {
376                 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
377                           win_errstr(werr));
378                 goto done;
379         }
380
381         ret = 0;
382
383 done:
384         TALLOC_FREE(ctx);
385         return ret;
386 }
387
388 static int net_registry_deletevalue(struct net_context *c, int argc,
389                                     const char **argv)
390 {
391         WERROR werr;
392         struct registry_key *key = NULL;
393         TALLOC_CTX *ctx = talloc_stackframe();
394         int ret = -1;
395
396         if (argc != 2 || c->display_usage) {
397                 d_fprintf(stderr, "%s\n%s",
398                           _("Usage:"),
399                           _("net rpc registry deletevalue <key> <valuename>\n"));
400                 goto done;
401         }
402
403         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
404         if (!W_ERROR_IS_OK(werr)) {
405                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
406                 goto done;
407         }
408
409         werr = reg_deletevalue(key, argv[1]);
410         if (!W_ERROR_IS_OK(werr)) {
411                 d_fprintf(stderr, _("reg_deletekey failed: %s\n"),
412                           win_errstr(werr));
413                 goto done;
414         }
415
416         ret = 0;
417
418 done:
419         TALLOC_FREE(ctx);
420         return ret;
421 }
422
423 static WERROR net_registry_getsd_internal(struct net_context *c,
424                                           TALLOC_CTX *mem_ctx,
425                                           const char *keyname,
426                                           struct security_descriptor **sd)
427 {
428         WERROR werr;
429         struct registry_key *key = NULL;
430         TALLOC_CTX *ctx = talloc_stackframe();
431         uint32_t access_mask = REG_KEY_READ |
432                                SEC_FLAG_MAXIMUM_ALLOWED |
433                                SEC_FLAG_SYSTEM_SECURITY;
434
435         /*
436          * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
437          * is denied with these perms right now...
438          */
439         access_mask = REG_KEY_READ;
440
441         if (sd == NULL) {
442                 d_fprintf(stderr, _("internal error: invalid argument\n"));
443                 werr = WERR_INVALID_PARAM;
444                 goto done;
445         }
446
447         if (strlen(keyname) == 0) {
448                 d_fprintf(stderr, _("error: zero length key name given\n"));
449                 werr = WERR_INVALID_PARAM;
450                 goto done;
451         }
452
453         werr = open_key(ctx, keyname, access_mask, &key);
454         if (!W_ERROR_IS_OK(werr)) {
455                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
456                 goto done;
457         }
458
459         werr = reg_getkeysecurity(mem_ctx, key, sd);
460         if (!W_ERROR_IS_OK(werr)) {
461                 d_fprintf(stderr, _("reg_getkeysecurity failed: %s\n"),
462                           win_errstr(werr));
463                 goto done;
464         }
465
466         werr = WERR_OK;
467
468 done:
469         TALLOC_FREE(ctx);
470         return werr;
471 }
472
473 static int net_registry_getsd(struct net_context *c, int argc,
474                               const char **argv)
475 {
476         WERROR werr;
477         int ret = -1;
478         struct security_descriptor *secdesc = NULL;
479         TALLOC_CTX *ctx = talloc_stackframe();
480
481         if (argc != 1 || c->display_usage) {
482                 d_printf("%s\n%s",
483                          _("Usage:"),
484                          _("net registry getsd <path>\n"));
485                 d_printf("%s\n%s",
486                          _("Example:"),
487                          _("net registry getsd 'HKLM\\Software\\Samba'\n"));
488                 goto done;
489         }
490
491         werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
492         if (!W_ERROR_IS_OK(werr)) {
493                 goto done;
494         }
495
496         display_sec_desc(secdesc);
497
498         ret = 0;
499
500 done:
501         TALLOC_FREE(ctx);
502         return ret;
503 }
504
505 static int net_registry_getsd_sddl(struct net_context *c,
506                                    int argc, const char **argv)
507 {
508         WERROR werr;
509         int ret = -1;
510         struct security_descriptor *secdesc = NULL;
511         TALLOC_CTX *ctx = talloc_stackframe();
512
513         if (argc != 1 || c->display_usage) {
514                 d_printf("%s\n%s",
515                          _("Usage:"),
516                          _("net registry getsd_sddl <path>\n"));
517                 d_printf("%s\n%s",
518                          _("Example:"),
519                          _("net registry getsd_sddl 'HKLM\\Software\\Samba'\n"));
520                 goto done;
521         }
522
523         werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
524         if (!W_ERROR_IS_OK(werr)) {
525                 goto done;
526         }
527
528         d_printf("%s\n", sddl_encode(ctx, secdesc, get_global_sam_sid()));
529
530         ret = 0;
531
532 done:
533         TALLOC_FREE(ctx);
534         return ret;
535 }
536
537 int net_registry(struct net_context *c, int argc, const char **argv)
538 {
539         int ret = -1;
540
541         struct functable func[] = {
542                 {
543                         "enumerate",
544                         net_registry_enumerate,
545                         NET_TRANSPORT_LOCAL,
546                         N_("Enumerate registry keys and values"),
547                         N_("net registry enumerate\n"
548                            "    Enumerate registry keys and values")
549                 },
550                 {
551                         "createkey",
552                         net_registry_createkey,
553                         NET_TRANSPORT_LOCAL,
554                         N_("Create a new registry key"),
555                         N_("net registry createkey\n"
556                            "    Create a new registry key")
557                 },
558                 {
559                         "deletekey",
560                         net_registry_deletekey,
561                         NET_TRANSPORT_LOCAL,
562                         N_("Delete a registry key"),
563                         N_("net registry deletekey\n"
564                            "    Delete a registry key")
565                 },
566                 {
567                         "getvalue",
568                         net_registry_getvalue,
569                         NET_TRANSPORT_LOCAL,
570                         N_("Print a registry value"),
571                         N_("net registry getvalue\n"
572                            "    Print a registry value")
573                 },
574                 {
575                         "getvalueraw",
576                         net_registry_getvalueraw,
577                         NET_TRANSPORT_LOCAL,
578                         N_("Print a registry value (raw format)"),
579                         N_("net registry getvalueraw\n"
580                            "    Print a registry value (raw format)")
581                 },
582                 {
583                         "setvalue",
584                         net_registry_setvalue,
585                         NET_TRANSPORT_LOCAL,
586                         N_("Set a new registry value"),
587                         N_("net registry setvalue\n"
588                            "    Set a new registry value")
589                 },
590                 {
591                         "deletevalue",
592                         net_registry_deletevalue,
593                         NET_TRANSPORT_LOCAL,
594                         N_("Delete a registry value"),
595                         N_("net registry deletevalue\n"
596                            "    Delete a registry value")
597                 },
598                 {
599                         "getsd",
600                         net_registry_getsd,
601                         NET_TRANSPORT_LOCAL,
602                         N_("Get security descriptor"),
603                         N_("net registry getsd\n"
604                            "    Get security descriptor")
605                 },
606                 {
607                         "getsd_sddl",
608                         net_registry_getsd_sddl,
609                         NET_TRANSPORT_LOCAL,
610                         N_("Get security descriptor in sddl format"),
611                         N_("net registry getsd_sddl\n"
612                            "    Get security descriptor in sddl format")
613                 },
614         { NULL, NULL, 0, NULL, NULL }
615         };
616
617         if (!W_ERROR_IS_OK(registry_init_basic())) {
618                 return -1;
619         }
620
621         ret = net_run_function(c, argc, argv, "net registry", func);
622
623         return ret;
624 }