s3 net/i18n: Use only one spelling for "Usage:"
[ira/wip.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(_("Usage:"),_("    net registry enumerate <path>\n"));
134                 d_printf(_("Example:"), _("  net registry enumerate "
135                          "'HKLM\\Software\\Samba'\n"));
136                 goto done;
137         }
138
139         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
140         if (!W_ERROR_IS_OK(werr)) {
141                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
142                 goto done;
143         }
144
145         for (count = 0;
146              werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
147              W_ERROR_IS_OK(werr);
148              count++)
149         {
150                 print_registry_key(subkey_name, &modtime);
151         }
152         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
153                 goto done;
154         }
155
156         for (count = 0;
157              werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
158              W_ERROR_IS_OK(werr);
159              count++)
160         {
161                 print_registry_value_with_name(valname, valvalue);
162         }
163         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
164                 goto done;
165         }
166
167         ret = 0;
168 done:
169         TALLOC_FREE(ctx);
170         return ret;
171 }
172
173 static int net_registry_createkey(struct net_context *c, int argc,
174                                   const char **argv)
175 {
176         WERROR werr;
177         enum winreg_CreateAction action;
178         char *subkeyname;
179         struct registry_key *hivekey = NULL;
180         struct registry_key *subkey = NULL;
181         TALLOC_CTX *ctx = talloc_stackframe();
182         int ret = -1;
183
184         if (argc != 1 || c->display_usage) {
185                 d_printf(_("Usage:"),_("    net registry createkey <path>\n"));
186                 d_printf(_("Example:"), _("  net registry createkey "
187                          "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
188                 goto done;
189         }
190         if (strlen(argv[0]) == 0) {
191                 d_fprintf(stderr, _("error: zero length key name given\n"));
192                 goto done;
193         }
194
195         werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
196         if (!W_ERROR_IS_OK(werr)) {
197                 d_fprintf(stderr, _("open_hive failed: %s\n"),
198                           win_errstr(werr));
199                 goto done;
200         }
201
202         werr = reg_createkey(ctx, hivekey, subkeyname, REG_KEY_WRITE,
203                              &subkey, &action);
204         if (!W_ERROR_IS_OK(werr)) {
205                 d_fprintf(stderr, _("reg_createkey failed: %s\n"),
206                           win_errstr(werr));
207                 goto done;
208         }
209         switch (action) {
210                 case REG_ACTION_NONE:
211                         d_printf(_("createkey did nothing -- huh?\n"));
212                         break;
213                 case REG_CREATED_NEW_KEY:
214                         d_printf(_("createkey created %s\n"), argv[0]);
215                         break;
216                 case REG_OPENED_EXISTING_KEY:
217                         d_printf(_("createkey opened existing %s\n"), argv[0]);
218                         break;
219         }
220
221         ret = 0;
222
223 done:
224         TALLOC_FREE(ctx);
225         return ret;
226 }
227
228 static int net_registry_deletekey(struct net_context *c, int argc,
229                                   const char **argv)
230 {
231         WERROR werr;
232         char *subkeyname;
233         struct registry_key *hivekey = NULL;
234         TALLOC_CTX *ctx = talloc_stackframe();
235         int ret = -1;
236
237         if (argc != 1 || c->display_usage) {
238                 d_printf(_("Usage:"),_("    net registry deletekey <path>\n"));
239                 d_printf(_("Example:"),_("  net registry deletekey "
240                            "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
241                 goto done;
242         }
243         if (strlen(argv[0]) == 0) {
244                 d_fprintf(stderr, _("error: zero length key name given\n"));
245                 goto done;
246         }
247
248         werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
249         if (!W_ERROR_IS_OK(werr)) {
250                 d_fprintf(stderr, "open_hive ", _("failed"),
251                         ": %s\n", win_errstr(werr));
252                 goto done;
253         }
254
255         werr = reg_deletekey(hivekey, subkeyname);
256         if (!W_ERROR_IS_OK(werr)) {
257                 d_fprintf(stderr, "reg_deletekey ", _("failed"), ": %s\n",
258                           win_errstr(werr));
259                 goto done;
260         }
261
262         ret = 0;
263
264 done:
265         TALLOC_FREE(ctx);
266         return ret;
267 }
268
269 static int net_registry_getvalue_internal(struct net_context *c, int argc,
270                                           const char **argv, bool raw)
271 {
272         WERROR werr;
273         int ret = -1;
274         struct registry_key *key = NULL;
275         struct registry_value *value = NULL;
276         TALLOC_CTX *ctx = talloc_stackframe();
277
278         if (argc != 2 || c->display_usage) {
279                 d_fprintf(stderr, _("Usage:"),_(" net rpc registry getvalue <key> "
280                                     "<valuename>\n"));
281                 goto done;
282         }
283
284         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
285         if (!W_ERROR_IS_OK(werr)) {
286                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
287                 goto done;
288         }
289
290         werr = reg_queryvalue(ctx, key, argv[1], &value);
291         if (!W_ERROR_IS_OK(werr)) {
292                 d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
293                           win_errstr(werr));
294                 goto done;
295         }
296
297         print_registry_value(value, raw);
298
299         ret = 0;
300
301 done:
302         TALLOC_FREE(ctx);
303         return ret;
304 }
305
306 static int net_registry_getvalue(struct net_context *c, int argc,
307                                  const char **argv)
308 {
309         return net_registry_getvalue_internal(c, argc, argv, false);
310 }
311
312 static int net_registry_getvalueraw(struct net_context *c, int argc,
313                                     const char **argv)
314 {
315         return net_registry_getvalue_internal(c, argc, argv, true);
316 }
317
318 static int net_registry_setvalue(struct net_context *c, int argc,
319                                  const char **argv)
320 {
321         WERROR werr;
322         struct registry_value value;
323         struct registry_key *key = NULL;
324         int ret = -1;
325         TALLOC_CTX *ctx = talloc_stackframe();
326
327         if (argc < 4 || c->display_usage) {
328                 d_fprintf(stderr, _("Usage:"),_(" net rpc registry setvalue <key> "
329                           "<valuename> <type> [<val>]+\n"));
330                 goto done;
331         }
332
333         if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
334                 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
335                 goto done;
336         }
337
338         if (strequal(argv[2], "dword")) {
339                 value.type = REG_DWORD;
340                 value.v.dword = strtoul(argv[3], NULL, 10);
341         } else if (strequal(argv[2], "sz")) {
342                 value.type = REG_SZ;
343                 value.v.sz.len = strlen(argv[3])+1;
344                 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
345         } else if (strequal(argv[2], "multi_sz")) {
346                 value.type = REG_MULTI_SZ;
347                 value.v.multi_sz.num_strings = argc - 3;
348                 value.v.multi_sz.strings = (char **)(argv + 3);
349         } else {
350                 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
351                 goto done;
352         }
353
354         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
355         if (!W_ERROR_IS_OK(werr)) {
356                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
357                 goto done;
358         }
359
360         werr = reg_setvalue(key, argv[1], &value);
361         if (!W_ERROR_IS_OK(werr)) {
362                 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
363                           win_errstr(werr));
364                 goto done;
365         }
366
367         ret = 0;
368
369 done:
370         TALLOC_FREE(ctx);
371         return ret;
372 }
373
374 static int net_registry_deletevalue(struct net_context *c, int argc,
375                                     const char **argv)
376 {
377         WERROR werr;
378         struct registry_key *key = NULL;
379         TALLOC_CTX *ctx = talloc_stackframe();
380         int ret = -1;
381
382         if (argc != 2 || c->display_usage) {
383                 d_fprintf(stderr, _("Usage:"),_(" net rpc registry deletevalue <key> "
384                           "<valuename>\n"));
385                 goto done;
386         }
387
388         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
389         if (!W_ERROR_IS_OK(werr)) {
390                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
391                 goto done;
392         }
393
394         werr = reg_deletevalue(key, argv[1]);
395         if (!W_ERROR_IS_OK(werr)) {
396                 d_fprintf(stderr, _("reg_deletekey failed: %s\n"),
397                           win_errstr(werr));
398                 goto done;
399         }
400
401         ret = 0;
402
403 done:
404         TALLOC_FREE(ctx);
405         return ret;
406 }
407
408 static int net_registry_getsd(struct net_context *c, int argc,
409                               const char **argv)
410 {
411         WERROR werr;
412         int ret = -1;
413         struct registry_key *key = NULL;
414         struct security_descriptor *secdesc = NULL;
415         TALLOC_CTX *ctx = talloc_stackframe();
416         uint32_t access_mask = REG_KEY_READ |
417                                SEC_FLAG_MAXIMUM_ALLOWED |
418                                SEC_FLAG_SYSTEM_SECURITY;
419
420         /*
421          * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
422          * is denied with these perms right now...
423          */
424         access_mask = REG_KEY_READ;
425
426         if (argc != 1 || c->display_usage) {
427                 d_printf(_("Usage:"),_("    net registry getsd <path>\n"));
428                 d_printf(_("Example:"),_("  net registry getsd "
429                            "'HKLM\\Software\\Samba'\n"));
430                 goto done;
431         }
432         if (strlen(argv[0]) == 0) {
433                 d_fprintf(stderr, "error: zero length key name given\n");
434                 goto done;
435         }
436
437         werr = open_key(ctx, argv[0], access_mask, &key);
438         if (!W_ERROR_IS_OK(werr)) {
439                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
440                 goto done;
441         }
442
443         werr = reg_getkeysecurity(ctx, key, &secdesc);
444         if (!W_ERROR_IS_OK(werr)) {
445                 d_fprintf(stderr, _("reg_getkeysecurity failed: %s\n"),
446                           win_errstr(werr));
447                 goto done;
448         }
449
450         display_sec_desc(secdesc);
451
452         ret = 0;
453
454 done:
455         TALLOC_FREE(ctx);
456         return ret;
457 }
458
459 int net_registry(struct net_context *c, int argc, const char **argv)
460 {
461         int ret = -1;
462
463         struct functable func[] = {
464                 {
465                         "enumerate",
466                         net_registry_enumerate,
467                         NET_TRANSPORT_LOCAL,
468                         N_("Enumerate registry keys and values"),
469                         N_("net registry enumerate\n"
470                            "    Enumerate registry keys and values")
471                 },
472                 {
473                         "createkey",
474                         net_registry_createkey,
475                         NET_TRANSPORT_LOCAL,
476                         N_("Create a new registry key"),
477                         N_("net registry createkey\n"
478                            "    Create a new registry key")
479                 },
480                 {
481                         "deletekey",
482                         net_registry_deletekey,
483                         NET_TRANSPORT_LOCAL,
484                         N_("Delete a registry key"),
485                         N_("net registry deletekey\n"
486                            "    Delete a registry key")
487                 },
488                 {
489                         "getvalue",
490                         net_registry_getvalue,
491                         NET_TRANSPORT_LOCAL,
492                         N_("Print a registry value"),
493                         N_("net registry getvalue\n"
494                            "    Print a registry value")
495                 },
496                 {
497                         "getvalueraw",
498                         net_registry_getvalueraw,
499                         NET_TRANSPORT_LOCAL,
500                         N_("Print a registry value (raw format)"),
501                         N_("net registry getvalueraw\n"
502                            "    Print a registry value (raw format)")
503                 },
504                 {
505                         "setvalue",
506                         net_registry_setvalue,
507                         NET_TRANSPORT_LOCAL,
508                         N_("Set a new registry value"),
509                         N_("net registry setvalue\n"
510                            "    Set a new registry value")
511                 },
512                 {
513                         "deletevalue",
514                         net_registry_deletevalue,
515                         NET_TRANSPORT_LOCAL,
516                         N_("Delete a registry value"),
517                         N_("net registry deletevalue\n"
518                            "    Delete a registry value")
519                 },
520                 {
521                         "getsd",
522                         net_registry_getsd,
523                         NET_TRANSPORT_LOCAL,
524                         N_("Get security descriptor"),
525                         N_("net registry getsd\n"
526                            "    Get security descriptor")
527                 },
528         { NULL, NULL, 0, NULL, NULL }
529         };
530
531         if (!W_ERROR_IS_OK(registry_init_basic())) {
532                 return -1;
533         }
534
535         ret = net_run_function(c, argc, argv, "net registry", func);
536
537         return ret;
538 }