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