53cce1236066507c91f8f3acfde9d8387a53a89b
[nivanova/samba-autobuild/.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 "registry.h"
24 #include "registry/reg_util_token.h"
25 #include "utils/net.h"
26 #include "utils/net_registry_util.h"
27 #include "include/g_lock.h"
28
29 /*
30  *
31  * Helper functions
32  *
33  */
34
35 /**
36  * split given path into hive and remaining path and open the hive key
37  */
38 static WERROR open_hive(TALLOC_CTX *ctx, const char *path,
39                         uint32 desired_access,
40                         struct registry_key **hive,
41                         char **subkeyname)
42 {
43         WERROR werr;
44         NT_USER_TOKEN *token = NULL;
45         char *hivename = NULL;
46         char *tmp_subkeyname = NULL;
47         TALLOC_CTX *tmp_ctx = talloc_stackframe();
48
49         if ((hive == NULL) || (subkeyname == NULL)) {
50                 werr = WERR_INVALID_PARAM;
51                 goto done;
52         }
53
54         werr = split_hive_key(tmp_ctx, path, &hivename, &tmp_subkeyname);
55         if (!W_ERROR_IS_OK(werr)) {
56                 goto done;
57         }
58         *subkeyname = talloc_strdup(ctx, tmp_subkeyname);
59         if (*subkeyname == NULL) {
60                 werr = WERR_NOMEM;
61                 goto done;
62         }
63
64         werr = ntstatus_to_werror(registry_create_admin_token(tmp_ctx, &token));
65         if (!W_ERROR_IS_OK(werr)) {
66                 goto done;
67         }
68
69         werr = reg_openhive(ctx, hivename, desired_access, token, hive);
70         if (!W_ERROR_IS_OK(werr)) {
71                 goto done;
72         }
73
74         werr = WERR_OK;
75
76 done:
77         TALLOC_FREE(tmp_ctx);
78         return werr;
79 }
80
81 static WERROR open_key(TALLOC_CTX *ctx, const char *path,
82                        uint32 desired_access,
83                        struct registry_key **key)
84 {
85         WERROR werr;
86         char *subkey_name = NULL;
87         struct registry_key *hive = NULL;
88         TALLOC_CTX *tmp_ctx = talloc_stackframe();
89
90         if ((path == NULL) || (key == NULL)) {
91                 return WERR_INVALID_PARAM;
92         }
93
94         werr = open_hive(tmp_ctx, path, desired_access, &hive, &subkey_name);
95         if (!W_ERROR_IS_OK(werr)) {
96                 d_fprintf(stderr, _("open_hive failed: %s\n"),
97                           win_errstr(werr));
98                 goto done;
99         }
100
101         werr = reg_openkey(ctx, hive, subkey_name, desired_access, key);
102         if (!W_ERROR_IS_OK(werr)) {
103                 d_fprintf(stderr, _("reg_openkey failed: %s\n"),
104                           win_errstr(werr));
105                 goto done;
106         }
107
108         werr = WERR_OK;
109
110 done:
111         TALLOC_FREE(tmp_ctx);
112         return werr;
113 }
114
115 /*
116  *
117  * the main "net registry" function implementations
118  *
119  */
120
121 static int net_registry_enumerate(struct net_context *c, int argc,
122                                   const char **argv)
123 {
124         WERROR werr;
125         struct registry_key *key = NULL;
126         TALLOC_CTX *ctx = talloc_stackframe();
127         char *subkey_name;
128         NTTIME modtime;
129         uint32_t count;
130         char *valname = NULL;
131         struct registry_value *valvalue = NULL;
132         int ret = -1;
133
134         if (argc != 1 || c->display_usage) {
135                 d_printf("%s\n%s",
136                          _("Usage:"),
137                          _("net registry enumerate <path>\n"));
138                 d_printf("%s\n%s",
139                          _("Example:"),
140                          _("net registry enumerate 'HKLM\\Software\\Samba'\n"));
141                 goto done;
142         }
143
144         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
145         if (!W_ERROR_IS_OK(werr)) {
146                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
147                 goto done;
148         }
149
150         for (count = 0;
151              werr = reg_enumkey(ctx, key, count, &subkey_name, &modtime),
152              W_ERROR_IS_OK(werr);
153              count++)
154         {
155                 print_registry_key(subkey_name, &modtime);
156         }
157         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
158                 goto done;
159         }
160
161         for (count = 0;
162              werr = reg_enumvalue(ctx, key, count, &valname, &valvalue),
163              W_ERROR_IS_OK(werr);
164              count++)
165         {
166                 print_registry_value_with_name(valname, valvalue);
167         }
168         if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) {
169                 goto done;
170         }
171
172         ret = 0;
173 done:
174         TALLOC_FREE(ctx);
175         return ret;
176 }
177
178 static int net_registry_createkey(struct net_context *c, int argc,
179                                   const char **argv)
180 {
181         WERROR werr;
182         enum winreg_CreateAction action;
183         char *subkeyname;
184         struct registry_key *hivekey = NULL;
185         struct registry_key *subkey = NULL;
186         TALLOC_CTX *ctx = talloc_stackframe();
187         int ret = -1;
188
189         if (argc != 1 || c->display_usage) {
190                 d_printf("%s\n%s",
191                          _("Usage:"),
192                          _("net registry createkey <path>\n"));
193                 d_printf("%s\n%s",
194                          _("Example:"),
195                          _("net registry createkey "
196                            "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
197                 goto done;
198         }
199         if (strlen(argv[0]) == 0) {
200                 d_fprintf(stderr, _("error: zero length key name given\n"));
201                 goto done;
202         }
203
204         werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
205         if (!W_ERROR_IS_OK(werr)) {
206                 d_fprintf(stderr, _("open_hive failed: %s\n"),
207                           win_errstr(werr));
208                 goto done;
209         }
210
211         werr = reg_createkey(ctx, hivekey, subkeyname, REG_KEY_WRITE,
212                              &subkey, &action);
213         if (!W_ERROR_IS_OK(werr)) {
214                 d_fprintf(stderr, _("reg_createkey failed: %s\n"),
215                           win_errstr(werr));
216                 goto done;
217         }
218         switch (action) {
219                 case REG_ACTION_NONE:
220                         d_printf(_("createkey did nothing -- huh?\n"));
221                         break;
222                 case REG_CREATED_NEW_KEY:
223                         d_printf(_("createkey created %s\n"), argv[0]);
224                         break;
225                 case REG_OPENED_EXISTING_KEY:
226                         d_printf(_("createkey opened existing %s\n"), argv[0]);
227                         break;
228         }
229
230         ret = 0;
231
232 done:
233         TALLOC_FREE(ctx);
234         return ret;
235 }
236
237 static int net_registry_deletekey(struct net_context *c, int argc,
238                                   const char **argv)
239 {
240         WERROR werr;
241         char *subkeyname;
242         struct registry_key *hivekey = NULL;
243         TALLOC_CTX *ctx = talloc_stackframe();
244         int ret = -1;
245
246         if (argc != 1 || c->display_usage) {
247                 d_printf("%s\n%s",
248                          _("Usage:"),
249                          _("net registry deletekey <path>\n"));
250                 d_printf("%s\n%s",
251                          _("Example:"),
252                          _("net registry deletekey "
253                            "'HKLM\\Software\\Samba\\smbconf.127.0.0.1'\n"));
254                 goto done;
255         }
256         if (strlen(argv[0]) == 0) {
257                 d_fprintf(stderr, _("error: zero length key name given\n"));
258                 goto done;
259         }
260
261         werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname);
262         if (!W_ERROR_IS_OK(werr)) {
263                 d_fprintf(stderr, "open_hive %s: %s\n", _("failed"),
264                           win_errstr(werr));
265                 goto done;
266         }
267
268         werr = reg_deletekey(hivekey, subkeyname);
269         if (!W_ERROR_IS_OK(werr)) {
270                 d_fprintf(stderr, "reg_deletekey %s: %s\n", _("failed"),
271                           win_errstr(werr));
272                 goto done;
273         }
274
275         ret = 0;
276
277 done:
278         TALLOC_FREE(ctx);
279         return ret;
280 }
281
282 static int net_registry_getvalue_internal(struct net_context *c, int argc,
283                                           const char **argv, bool raw)
284 {
285         WERROR werr;
286         int ret = -1;
287         struct registry_key *key = NULL;
288         struct registry_value *value = NULL;
289         TALLOC_CTX *ctx = talloc_stackframe();
290
291         if (argc != 2 || c->display_usage) {
292                 d_fprintf(stderr, "%s\n%s",
293                           _("Usage:"),
294                           _("net registry getvalue <key> <valuename>\n"));
295                 goto done;
296         }
297
298         werr = open_key(ctx, argv[0], REG_KEY_READ, &key);
299         if (!W_ERROR_IS_OK(werr)) {
300                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
301                 goto done;
302         }
303
304         werr = reg_queryvalue(ctx, key, argv[1], &value);
305         if (!W_ERROR_IS_OK(werr)) {
306                 d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
307                           win_errstr(werr));
308                 goto done;
309         }
310
311         print_registry_value(value, raw);
312
313         ret = 0;
314
315 done:
316         TALLOC_FREE(ctx);
317         return ret;
318 }
319
320 static int net_registry_getvalue(struct net_context *c, int argc,
321                                  const char **argv)
322 {
323         return net_registry_getvalue_internal(c, argc, argv, false);
324 }
325
326 static int net_registry_getvalueraw(struct net_context *c, int argc,
327                                     const char **argv)
328 {
329         return net_registry_getvalue_internal(c, argc, argv, true);
330 }
331
332 static int net_registry_setvalue(struct net_context *c, int argc,
333                                  const char **argv)
334 {
335         WERROR werr;
336         struct registry_value value;
337         struct registry_key *key = NULL;
338         int ret = -1;
339         TALLOC_CTX *ctx = talloc_stackframe();
340
341         if (argc < 4 || c->display_usage) {
342                 d_fprintf(stderr, "%s\n%s",
343                           _("Usage:"),
344                           _("net registry setvalue <key> <valuename> "
345                             "<type> [<val>]+\n"));
346                 goto done;
347         }
348
349         if (!strequal(argv[2], "multi_sz") && (argc != 4)) {
350                 d_fprintf(stderr, _("Too many args for type %s\n"), argv[2]);
351                 goto done;
352         }
353
354         if (strequal(argv[2], "dword")) {
355                 value.type = REG_DWORD;
356                 value.v.dword = strtoul(argv[3], NULL, 10);
357         } else if (strequal(argv[2], "sz")) {
358                 value.type = REG_SZ;
359                 value.v.sz.len = strlen(argv[3])+1;
360                 value.v.sz.str = CONST_DISCARD(char *, argv[3]);
361         } else if (strequal(argv[2], "multi_sz")) {
362                 value.type = REG_MULTI_SZ;
363                 value.v.multi_sz.num_strings = argc - 3;
364                 value.v.multi_sz.strings = (char **)(argv + 3);
365         } else {
366                 d_fprintf(stderr, _("type \"%s\" not implemented\n"), argv[2]);
367                 goto done;
368         }
369
370         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
371         if (!W_ERROR_IS_OK(werr)) {
372                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
373                 goto done;
374         }
375
376         werr = reg_setvalue(key, argv[1], &value);
377         if (!W_ERROR_IS_OK(werr)) {
378                 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
379                           win_errstr(werr));
380                 goto done;
381         }
382
383         ret = 0;
384
385 done:
386         TALLOC_FREE(ctx);
387         return ret;
388 }
389
390 struct net_registry_increment_state {
391         const char *keyname;
392         const char *valuename;
393         uint32_t increment;
394         uint32_t newvalue;
395         WERROR werr;
396 };
397
398 static void net_registry_increment_fn(void *private_data)
399 {
400         struct net_registry_increment_state *state =
401                 (struct net_registry_increment_state *)private_data;
402         struct registry_value *value;
403         struct registry_key *key = NULL;
404
405         state->werr = open_key(talloc_tos(), state->keyname,
406                                REG_KEY_READ|REG_KEY_WRITE, &key);
407         if (!W_ERROR_IS_OK(state->werr)) {
408                 d_fprintf(stderr, _("open_key failed: %s\n"),
409                           win_errstr(state->werr));
410                 goto done;
411         }
412
413         state->werr = reg_queryvalue(key, key, state->valuename, &value);
414         if (!W_ERROR_IS_OK(state->werr)) {
415                 d_fprintf(stderr, _("reg_queryvalue failed: %s\n"),
416                           win_errstr(state->werr));
417                 goto done;
418         }
419
420         if (value->type != REG_DWORD) {
421                 d_fprintf(stderr, _("value not a DWORD: %s\n"),
422                           str_regtype(value->type));
423                 goto done;
424         }
425
426         value->v.dword += state->increment;
427         state->newvalue = value->v.dword;
428
429         state->werr = reg_setvalue(key, state->valuename, value);
430         if (!W_ERROR_IS_OK(state->werr)) {
431                 d_fprintf(stderr, _("reg_setvalue failed: %s\n"),
432                           win_errstr(state->werr));
433                 goto done;
434         }
435
436 done:
437         TALLOC_FREE(key);
438         return;
439 }
440
441 static int net_registry_increment(struct net_context *c, int argc,
442                                   const char **argv)
443 {
444         struct net_registry_increment_state state;
445         NTSTATUS status;
446         int ret = -1;
447
448         if (argc < 2 || c->display_usage) {
449                 d_fprintf(stderr, "%s\n%s",
450                           _("Usage:"),
451                           _("net registry increment <key> <valuename> "
452                             "[<increment>]\n"));
453                 goto done;
454         }
455
456         state.keyname = argv[0];
457         state.valuename = argv[1];
458
459         state.increment = 1;
460         if (argc == 3) {
461                 state.increment = strtoul(argv[2], NULL, 10);
462         }
463
464         status = g_lock_do("registry_increment_lock", G_LOCK_WRITE,
465                            timeval_set(600, 0),
466                            net_registry_increment_fn, &state);
467         if (!NT_STATUS_IS_OK(status)) {
468                 d_fprintf(stderr, _("g_lock_do failed: %s\n"),
469                           nt_errstr(status));
470                 goto done;
471         }
472         if (!W_ERROR_IS_OK(state.werr)) {
473                 d_fprintf(stderr, _("increment failed: %s\n"),
474                           win_errstr(state.werr));
475                 goto done;
476         }
477
478         d_printf(_("%u\n"), (unsigned)state.newvalue);
479
480         ret = 0;
481
482 done:
483         return ret;
484 }
485
486 static int net_registry_deletevalue(struct net_context *c, int argc,
487                                     const char **argv)
488 {
489         WERROR werr;
490         struct registry_key *key = NULL;
491         TALLOC_CTX *ctx = talloc_stackframe();
492         int ret = -1;
493
494         if (argc != 2 || c->display_usage) {
495                 d_fprintf(stderr, "%s\n%s",
496                           _("Usage:"),
497                           _("net registry deletevalue <key> <valuename>\n"));
498                 goto done;
499         }
500
501         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
502         if (!W_ERROR_IS_OK(werr)) {
503                 d_fprintf(stderr, _("open_key failed: %s\n"), win_errstr(werr));
504                 goto done;
505         }
506
507         werr = reg_deletevalue(key, argv[1]);
508         if (!W_ERROR_IS_OK(werr)) {
509                 d_fprintf(stderr, _("reg_deletekey failed: %s\n"),
510                           win_errstr(werr));
511                 goto done;
512         }
513
514         ret = 0;
515
516 done:
517         TALLOC_FREE(ctx);
518         return ret;
519 }
520
521 static WERROR net_registry_getsd_internal(struct net_context *c,
522                                           TALLOC_CTX *mem_ctx,
523                                           const char *keyname,
524                                           struct security_descriptor **sd)
525 {
526         WERROR werr;
527         struct registry_key *key = NULL;
528         TALLOC_CTX *ctx = talloc_stackframe();
529         uint32_t access_mask = REG_KEY_READ |
530                                SEC_FLAG_MAXIMUM_ALLOWED |
531                                SEC_FLAG_SYSTEM_SECURITY;
532
533         /*
534          * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
535          * is denied with these perms right now...
536          */
537         access_mask = REG_KEY_READ;
538
539         if (sd == NULL) {
540                 d_fprintf(stderr, _("internal error: invalid argument\n"));
541                 werr = WERR_INVALID_PARAM;
542                 goto done;
543         }
544
545         if (strlen(keyname) == 0) {
546                 d_fprintf(stderr, _("error: zero length key name given\n"));
547                 werr = WERR_INVALID_PARAM;
548                 goto done;
549         }
550
551         werr = open_key(ctx, keyname, access_mask, &key);
552         if (!W_ERROR_IS_OK(werr)) {
553                 d_fprintf(stderr, "%s%s\n", _("open_key failed: "),
554                           win_errstr(werr));
555                 goto done;
556         }
557
558         werr = reg_getkeysecurity(mem_ctx, key, sd);
559         if (!W_ERROR_IS_OK(werr)) {
560                 d_fprintf(stderr, "%s%s\n", _("reg_getkeysecurity failed: "),
561                           win_errstr(werr));
562                 goto done;
563         }
564
565         werr = WERR_OK;
566
567 done:
568         TALLOC_FREE(ctx);
569         return werr;
570 }
571
572 static int net_registry_getsd(struct net_context *c, int argc,
573                               const char **argv)
574 {
575         WERROR werr;
576         int ret = -1;
577         struct security_descriptor *secdesc = NULL;
578         TALLOC_CTX *ctx = talloc_stackframe();
579
580         if (argc != 1 || c->display_usage) {
581                 d_printf("%s\n%s",
582                          _("Usage:"),
583                          _("net registry getsd <path>\n"));
584                 d_printf("%s\n%s",
585                          _("Example:"),
586                          _("net registry getsd 'HKLM\\Software\\Samba'\n"));
587                 goto done;
588         }
589
590         werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
591         if (!W_ERROR_IS_OK(werr)) {
592                 goto done;
593         }
594
595         display_sec_desc(secdesc);
596
597         ret = 0;
598
599 done:
600         TALLOC_FREE(ctx);
601         return ret;
602 }
603
604 static int net_registry_getsd_sddl(struct net_context *c,
605                                    int argc, const char **argv)
606 {
607         WERROR werr;
608         int ret = -1;
609         struct security_descriptor *secdesc = NULL;
610         TALLOC_CTX *ctx = talloc_stackframe();
611
612         if (argc != 1 || c->display_usage) {
613                 d_printf("%s\n%s",
614                          _("Usage:"),
615                          _("net registry getsd_sddl <path>\n"));
616                 d_printf("%s\n%s",
617                          _("Example:"),
618                          _("net registry getsd_sddl 'HKLM\\Software\\Samba'\n"));
619                 goto done;
620         }
621
622         werr = net_registry_getsd_internal(c, ctx, argv[0], &secdesc);
623         if (!W_ERROR_IS_OK(werr)) {
624                 goto done;
625         }
626
627         d_printf("%s\n", sddl_encode(ctx, secdesc, get_global_sam_sid()));
628
629         ret = 0;
630
631 done:
632         TALLOC_FREE(ctx);
633         return ret;
634 }
635
636 static WERROR net_registry_setsd_internal(struct net_context *c,
637                                           TALLOC_CTX *mem_ctx,
638                                           const char *keyname,
639                                           struct security_descriptor *sd)
640 {
641         WERROR werr;
642         struct registry_key *key = NULL;
643         TALLOC_CTX *ctx = talloc_stackframe();
644         uint32_t access_mask = REG_KEY_WRITE |
645                                SEC_FLAG_MAXIMUM_ALLOWED |
646                                SEC_FLAG_SYSTEM_SECURITY;
647
648         /*
649          * net_rpc_regsitry uses SEC_FLAG_SYSTEM_SECURITY, but access
650          * is denied with these perms right now...
651          */
652         access_mask = REG_KEY_WRITE;
653
654         if (strlen(keyname) == 0) {
655                 d_fprintf(stderr, _("error: zero length key name given\n"));
656                 werr = WERR_INVALID_PARAM;
657                 goto done;
658         }
659
660         werr = open_key(ctx, keyname, access_mask, &key);
661         if (!W_ERROR_IS_OK(werr)) {
662                 d_fprintf(stderr, "%s%s\n", _("open_key failed: "),
663                           win_errstr(werr));
664                 goto done;
665         }
666
667         werr = reg_setkeysecurity(key, sd);
668         if (!W_ERROR_IS_OK(werr)) {
669                 d_fprintf(stderr, "%s%s\n", _("reg_setkeysecurity failed: "),
670                           win_errstr(werr));
671                 goto done;
672         }
673
674         werr = WERR_OK;
675
676 done:
677         TALLOC_FREE(ctx);
678         return werr;
679 }
680
681 static int net_registry_setsd_sddl(struct net_context *c,
682                                    int argc, const char **argv)
683 {
684         WERROR werr;
685         int ret = -1;
686         struct security_descriptor *secdesc = NULL;
687         TALLOC_CTX *ctx = talloc_stackframe();
688
689         if (argc != 2 || c->display_usage) {
690                 d_printf("%s\n%s",
691                          _("Usage:"),
692                          _("net registry setsd_sddl <path> <security_descriptor>\n"));
693                 d_printf("%s\n%s",
694                          _("Example:"),
695                          _("net registry setsd_sddl 'HKLM\\Software\\Samba'\n"));
696                 goto done;
697         }
698
699         secdesc = sddl_decode(ctx, argv[1], get_global_sam_sid());
700         if (secdesc == NULL) {
701                 goto done;
702         }
703
704         werr = net_registry_setsd_internal(c, ctx, argv[0], secdesc);
705         if (!W_ERROR_IS_OK(werr)) {
706                 goto done;
707         }
708
709         ret = 0;
710
711 done:
712         TALLOC_FREE(ctx);
713         return ret;
714 }
715
716 int net_registry(struct net_context *c, int argc, const char **argv)
717 {
718         int ret = -1;
719
720         struct functable func[] = {
721                 {
722                         "enumerate",
723                         net_registry_enumerate,
724                         NET_TRANSPORT_LOCAL,
725                         N_("Enumerate registry keys and values"),
726                         N_("net registry enumerate\n"
727                            "    Enumerate registry keys and values")
728                 },
729                 {
730                         "createkey",
731                         net_registry_createkey,
732                         NET_TRANSPORT_LOCAL,
733                         N_("Create a new registry key"),
734                         N_("net registry createkey\n"
735                            "    Create a new registry key")
736                 },
737                 {
738                         "deletekey",
739                         net_registry_deletekey,
740                         NET_TRANSPORT_LOCAL,
741                         N_("Delete a registry key"),
742                         N_("net registry deletekey\n"
743                            "    Delete a registry key")
744                 },
745                 {
746                         "getvalue",
747                         net_registry_getvalue,
748                         NET_TRANSPORT_LOCAL,
749                         N_("Print a registry value"),
750                         N_("net registry getvalue\n"
751                            "    Print a registry value")
752                 },
753                 {
754                         "getvalueraw",
755                         net_registry_getvalueraw,
756                         NET_TRANSPORT_LOCAL,
757                         N_("Print a registry value (raw format)"),
758                         N_("net registry getvalueraw\n"
759                            "    Print a registry value (raw format)")
760                 },
761                 {
762                         "setvalue",
763                         net_registry_setvalue,
764                         NET_TRANSPORT_LOCAL,
765                         N_("Set a new registry value"),
766                         N_("net registry setvalue\n"
767                            "    Set a new registry value")
768                 },
769                 {
770                         "increment",
771                         net_registry_increment,
772                         NET_TRANSPORT_LOCAL,
773                         N_("Increment a DWORD registry value under a lock"),
774                         N_("net registry increment\n"
775                            "    Increment a DWORD registry value under a lock")
776                 },
777                 {
778                         "deletevalue",
779                         net_registry_deletevalue,
780                         NET_TRANSPORT_LOCAL,
781                         N_("Delete a registry value"),
782                         N_("net registry deletevalue\n"
783                            "    Delete a registry value")
784                 },
785                 {
786                         "getsd",
787                         net_registry_getsd,
788                         NET_TRANSPORT_LOCAL,
789                         N_("Get security descriptor"),
790                         N_("net registry getsd\n"
791                            "    Get security descriptor")
792                 },
793                 {
794                         "getsd_sddl",
795                         net_registry_getsd_sddl,
796                         NET_TRANSPORT_LOCAL,
797                         N_("Get security descriptor in sddl format"),
798                         N_("net registry getsd_sddl\n"
799                            "    Get security descriptor in sddl format")
800                 },
801                 {
802                         "setsd_sddl",
803                         net_registry_setsd_sddl,
804                         NET_TRANSPORT_LOCAL,
805                         N_("Set security descriptor from sddl format string"),
806                         N_("net registry setsd_sddl\n"
807                            "    Set security descriptor from sddl format string")
808                 },
809         { NULL, NULL, 0, NULL, NULL }
810         };
811
812         if (!W_ERROR_IS_OK(registry_init_basic())) {
813                 return -1;
814         }
815
816         ret = net_run_function(c, argc, argv, "net registry", func);
817
818         return ret;
819 }