net: Rename functable3 to functable, get rid of old functables
[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", dos_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                           dos_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", dos_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", dos_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                           dos_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", dos_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                           dos_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", dos_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                           dos_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 {
343                 d_fprintf(stderr, "type \"%s\" not implemented\n", argv[2]);
344                 goto done;
345         }
346
347         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
348         if (!W_ERROR_IS_OK(werr)) {
349                 d_fprintf(stderr, "open_key failed: %s\n", dos_errstr(werr));
350                 goto done;
351         }
352
353         werr = reg_setvalue(key, argv[1], &value);
354         if (!W_ERROR_IS_OK(werr)) {
355                 d_fprintf(stderr, "reg_setvalue failed: %s\n",
356                           dos_errstr(werr));
357                 goto done;
358         }
359
360         ret = 0;
361
362 done:
363         TALLOC_FREE(ctx);
364         return ret;
365 }
366
367 static int net_registry_deletevalue(struct net_context *c, int argc,
368                                     const char **argv)
369 {
370         WERROR werr;
371         struct registry_key *key = NULL;
372         TALLOC_CTX *ctx = talloc_stackframe();
373         int ret = -1;
374
375         if (argc != 2 || c->display_usage) {
376                 d_fprintf(stderr, "usage: net rpc registry deletevalue <key> "
377                           "<valuename>\n");
378                 goto done;
379         }
380
381         werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key);
382         if (!W_ERROR_IS_OK(werr)) {
383                 d_fprintf(stderr, "open_key failed: %s\n", dos_errstr(werr));
384                 goto done;
385         }
386
387         werr = reg_deletevalue(key, argv[1]);
388         if (!W_ERROR_IS_OK(werr)) {
389                 d_fprintf(stderr, "reg_deletekey failed: %s\n",
390                           dos_errstr(werr));
391                 goto done;
392         }
393
394         ret = 0;
395
396 done:
397         TALLOC_FREE(ctx);
398         return ret;
399 }
400
401 static int net_registry_getsd(struct net_context *c, int argc,
402                               const char **argv)
403 {
404         WERROR werr;
405         int ret = -1;
406         struct registry_key *key = NULL;
407         struct security_descriptor *secdesc = NULL;
408         TALLOC_CTX *ctx = talloc_stackframe();
409         uint32_t access_mask = REG_KEY_READ |
410                                SEC_RIGHT_MAXIMUM_ALLOWED |
411                                SEC_RIGHT_SYSTEM_SECURITY;
412
413         /*
414          * net_rpc_regsitry uses SEC_RIGHT_SYSTEM_SECURITY, but access
415          * is denied with these perms right now...
416          */
417         access_mask = REG_KEY_READ;
418
419         if (argc != 1 || c->display_usage) {
420                 d_printf("Usage:    net registry getsd <path>\n");
421                 d_printf("Example:  net registry getsd "
422                          "'HKLM\\Software\\Samba'\n");
423                 goto done;
424         }
425         if (strlen(argv[0]) == 0) {
426                 d_fprintf(stderr, "error: zero length key name given\n");
427                 goto done;
428         }
429
430         werr = open_key(ctx, argv[0], access_mask, &key);
431         if (!W_ERROR_IS_OK(werr)) {
432                 d_fprintf(stderr, "open_key failed: %s\n", dos_errstr(werr));
433                 goto done;
434         }
435
436         werr = reg_getkeysecurity(ctx, key, &secdesc);
437         if (!W_ERROR_IS_OK(werr)) {
438                 d_fprintf(stderr, "reg_getkeysecurity failed: %s\n",
439                           dos_errstr(werr));
440                 goto done;
441         }
442
443         display_sec_desc(secdesc);
444
445         ret = 0;
446
447 done:
448         TALLOC_FREE(ctx);
449         return ret;
450 }
451
452 int net_registry(struct net_context *c, int argc, const char **argv)
453 {
454         int ret = -1;
455
456         struct functable func[] = {
457                 {
458                         "enumerate",
459                         net_registry_enumerate,
460                         NET_TRANSPORT_LOCAL,
461                         "Enumerate registry keys and values",
462                         "net registry enumerate\n"
463                         "    Enumerate registry keys and values"
464                 },
465                 {
466                         "createkey",
467                         net_registry_createkey,
468                         NET_TRANSPORT_LOCAL,
469                         "Create a new registry key",
470                         "net registry createkey\n"
471                         "    Create a new registry key"
472                 },
473                 {
474                         "deletekey",
475                         net_registry_deletekey,
476                         NET_TRANSPORT_LOCAL,
477                         "Delete a registry key",
478                         "net registry deletekey\n"
479                         "    Delete a registry key"
480                 },
481                 {
482                         "getvalue",
483                         net_registry_getvalue,
484                         NET_TRANSPORT_LOCAL,
485                         "Print a registry value",
486                         "net registry getvalue\n"
487                         "    Print a registry value"
488                 },
489                 {
490                         "getvalueraw",
491                         net_registry_getvalueraw,
492                         NET_TRANSPORT_LOCAL,
493                         "Print a registry value (raw format)",
494                         "net registry getvalueraw\n"
495                         "    Print a registry value (raw format)"
496                 },
497                 {
498                         "setvalue",
499                         net_registry_setvalue,
500                         NET_TRANSPORT_LOCAL,
501                         "Set a new registry value",
502                         "net registry setvalue\n"
503                         "    Set a new registry value"
504                 },
505                 {
506                         "deletevalue",
507                         net_registry_deletevalue,
508                         NET_TRANSPORT_LOCAL,
509                         "Delete a registry value",
510                         "net registry deletevalue\n"
511                         "    Delete a registry value"
512                 },
513                 {
514                         "getsd",
515                         net_registry_getsd,
516                         NET_TRANSPORT_LOCAL,
517                         "Get security descriptor",
518                         "net registry getsd\n"
519                         "    Get security descriptor"
520                 },
521         { NULL, NULL, 0, NULL, NULL }
522         };
523
524         if (!W_ERROR_IS_OK(registry_init_basic())) {
525                 return -1;
526         }
527
528         ret = net_run_function(c, argc, argv, "net registry", func);
529
530         return ret;
531 }